reactive-dashboard-performance

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Reactive Dashboard Performance

响应式仪表盘性能优化

Expert in building production-grade reactive dashboards that load in <100ms and have comprehensive test coverage.
精通构建生产级响应式仪表盘,实现加载时间<100ms并具备全面测试覆盖率。

Core Expertise

核心技术专长

Performance Patterns (Linear, Vercel, Notion-grade)

性能优化模式(对标Linear、Vercel、Notion级别)

  1. Skeleton-First Loading
    • Render skeleton immediately (0ms perceived load)
    • Stream in data progressively
    • Never show spinners for <200ms loads
  2. Aggressive Caching
    • React Query with staleTime: 5min, cacheTime: 30min
    • Optimistic updates for mutations
    • Prefetch on hover/mount
  3. Code Splitting
    • Route-based splitting (Next.js automatic)
    • Component-level lazy() for heavy widgets
    • Preload critical paths
  4. Memoization Strategy
    • useMemo for expensive computations
    • React.memo for pure components
    • useCallback for stable references
  1. 骨架屏优先加载
    • 立即渲染骨架屏(感知加载时间0ms)
    • 渐进式流式加载数据
    • 对于加载时间<200ms的内容,绝不显示加载动画
  2. 激进式缓存策略
    • 使用React Query,配置staleTime: 5分钟,cacheTime: 30分钟
    • 针对数据变更操作使用乐观更新
    • 在鼠标悬停/组件挂载时预加载数据
  3. 代码分割
    • 基于路由的代码分割(Next.js自动实现)
    • 对重型组件使用lazy()进行组件级分割
    • 预加载关键路径代码
  4. 记忆化策略
    • 对昂贵计算逻辑使用useMemo
    • 对纯组件使用React.memo
    • 对稳定引用使用useCallback

Testing Reactive Dashboards

响应式仪表盘测试

  1. Mock Strategy
    • Mock at service boundary (React Query, analytics)
    • Never mock UI components (test real DOM)
    • Use MSW for API mocking when possible
  2. Async Handling
    typescript
    // WRONG - races with React
    render(<Dashboard />);
    const element = screen.getByText('Welcome');
    
    // RIGHT - waits for async resolution
    render(<Dashboard />);
    const element = await screen.findByText('Welcome');
  3. Timeout Debugging
    • Timeouts mean: missing mock, wrong query, or component not rendering
    • Use screen.debug() to see actual DOM
    • Check console for unmocked errors
  4. Test Wrapper Pattern
    typescript
    const TestProviders = ({ children }) => (
      <QueryClientProvider client={testQueryClient}>
        <AuthProvider>
          {children}
        </AuthProvider>
      </QueryClientProvider>
    );
  1. Mock策略
    • 在服务边界层进行Mock(如React Query、分析工具)
    • 绝不Mock UI组件(测试真实DOM)
    • 尽可能使用MSW进行API Mock
  2. 异步处理
    typescript
    // 错误写法 - 会与React执行顺序冲突
    render(<Dashboard />);
    const element = screen.getByText('Welcome');
    
    // 正确写法 - 等待异步操作完成
    render(<Dashboard />);
    const element = await screen.findByText('Welcome');
  3. 超时问题调试
    • 超时通常意味着:缺失Mock、查询错误或组件未渲染
    • 使用screen.debug()查看实际DOM内容
    • 检查控制台是否存在未Mock的错误
  4. 测试包装器模式
    typescript
    const TestProviders = ({ children }) => (
      <QueryClientProvider client={testQueryClient}>
        <AuthProvider>
          {children}
        </AuthProvider>
      </QueryClientProvider>
    );

Real-World Examples

实战案例

  • Linear Dashboard: Skeleton → Stale data → Fresh data (perceived <50ms)
  • Vercel Dashboard: Prefetch on nav hover, optimistic deploys
  • Notion Pages: Infinite cache, local-first, sync in background
  • Linear仪表盘:骨架屏 → 过期缓存数据 → 最新数据(感知加载时间<50ms)
  • Vercel仪表盘:导航悬停时预加载,部署操作使用乐观更新
  • Notion页面:无限缓存、本地优先、后台同步

Diagnostic Protocol

诊断流程

Integration Test Timeouts

集成测试超时问题

  1. Check what's actually rendering
    typescript
    render(<Component />);
    screen.debug(); // See actual DOM
  2. Find unmocked dependencies
    • Check console for "not a function" errors
    • Look for network requests in test output
    • Verify all contexts are provided
  3. Fix async queries
    • Use findBy* instead of getBy*
    • Increase timeout if needed:
      waitFor(() =&gt; {...}, { timeout: 3000 })
    • Mock React Query properly
  4. Simplify component tree
    • Test widgets individually first
    • Add full integration tests last
    • Use data-testid for complex queries
  1. 检查实际渲染内容
    typescript
    render(<Component />);
    screen.debug(); // 查看实际DOM
  2. 查找未Mock的依赖
    • 检查控制台是否存在“not a function”类错误
    • 在测试输出中查看网络请求
    • 验证所有上下文是否已提供
  3. 修复异步查询问题
    • 使用findBy替代getBy
    • 必要时增加超时时间:
      waitFor(() => {...}, { timeout: 3000 })
    • 正确Mock React Query
  4. 简化组件树
    • 先单独测试各个小组件
    • 最后添加完整集成测试
    • 对复杂查询使用data-testid

Performance Optimization

性能优化

Dashboard Load Budget

仪表盘加载预算

PhaseTarget
Skeleton render0-16ms (1 frame)
First data paint<100ms
Full interactive<200ms
Lazy widgets<500ms
阶段目标
骨架屏渲染0-16ms(1帧)
首次数据渲染<100ms
完全交互状态<200ms
懒加载组件<500ms

React Query Config

React Query配置

typescript
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000, // 5min
      cacheTime: 30 * 60 * 1000, // 30min
      refetchOnWindowFocus: false,
      refetchOnMount: false,
      retry: 1,
    },
  },
});
typescript
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000, // 5分钟
      cacheTime: 30 * 60 * 1000, // 30分钟
      refetchOnWindowFocus: false,
      refetchOnMount: false,
      retry: 1,
    },
  },
});

Skeleton Pattern

骨架屏模式

typescript
function Dashboard() {
  const { data, isLoading } = useQuery('dashboard', fetchDashboard);

  // Show skeleton immediately, no loading check
  return (
    <div>
      {data ? <RealWidget data={data} /> : <SkeletonWidget />}
    </div>
  );
}
typescript
function Dashboard() {
  const { data, isLoading } = useQuery('dashboard', fetchDashboard);

  // 立即显示骨架屏,无需检查加载状态
  return (
    <div>
      {data ? <RealWidget data={data} /> : <SkeletonWidget />}
    </div>
  );
}

Common Pitfalls

常见误区

  1. Spinners for fast loads - Use skeletons instead
  2. Unmemoized expensive computations - Wrap in useMemo
  3. Testing implementation details - Test user behavior
  4. Mocking too much - Mock at boundaries only
  5. Synchronous test expectations - Everything is async
When debugging test timeouts, ALWAYS start with
screen.debug()
to see what actually rendered.
  1. 为快速加载内容显示动画 - 改用骨架屏
  2. 未记忆化的昂贵计算 - 使用useMemo包裹
  3. 测试实现细节 - 测试用户行为而非内部实现
  4. 过度Mock - 仅在边界层进行Mock
  5. 同步测试预期 - 所有操作均为异步
调试测试超时问题时,务必从
screen.debug()
开始,查看实际渲染内容。