reactive-dashboard-performance
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReactive 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级别)
-
Skeleton-First Loading
- Render skeleton immediately (0ms perceived load)
- Stream in data progressively
- Never show spinners for <200ms loads
-
Aggressive Caching
- React Query with staleTime: 5min, cacheTime: 30min
- Optimistic updates for mutations
- Prefetch on hover/mount
-
Code Splitting
- Route-based splitting (Next.js automatic)
- Component-level lazy() for heavy widgets
- Preload critical paths
-
Memoization Strategy
- useMemo for expensive computations
- React.memo for pure components
- useCallback for stable references
-
骨架屏优先加载
- 立即渲染骨架屏(感知加载时间0ms)
- 渐进式流式加载数据
- 对于加载时间<200ms的内容,绝不显示加载动画
-
激进式缓存策略
- 使用React Query,配置staleTime: 5分钟,cacheTime: 30分钟
- 针对数据变更操作使用乐观更新
- 在鼠标悬停/组件挂载时预加载数据
-
代码分割
- 基于路由的代码分割(Next.js自动实现)
- 对重型组件使用lazy()进行组件级分割
- 预加载关键路径代码
-
记忆化策略
- 对昂贵计算逻辑使用useMemo
- 对纯组件使用React.memo
- 对稳定引用使用useCallback
Testing Reactive Dashboards
响应式仪表盘测试
-
Mock Strategy
- Mock at service boundary (React Query, analytics)
- Never mock UI components (test real DOM)
- Use MSW for API mocking when possible
-
Async Handlingtypescript
// WRONG - races with React render(<Dashboard />); const element = screen.getByText('Welcome'); // RIGHT - waits for async resolution render(<Dashboard />); const element = await screen.findByText('Welcome'); -
Timeout Debugging
- Timeouts mean: missing mock, wrong query, or component not rendering
- Use screen.debug() to see actual DOM
- Check console for unmocked errors
-
Test Wrapper Patterntypescript
const TestProviders = ({ children }) => ( <QueryClientProvider client={testQueryClient}> <AuthProvider> {children} </AuthProvider> </QueryClientProvider> );
-
Mock策略
- 在服务边界层进行Mock(如React Query、分析工具)
- 绝不Mock UI组件(测试真实DOM)
- 尽可能使用MSW进行API Mock
-
异步处理typescript
// 错误写法 - 会与React执行顺序冲突 render(<Dashboard />); const element = screen.getByText('Welcome'); // 正确写法 - 等待异步操作完成 render(<Dashboard />); const element = await screen.findByText('Welcome'); -
超时问题调试
- 超时通常意味着:缺失Mock、查询错误或组件未渲染
- 使用screen.debug()查看实际DOM内容
- 检查控制台是否存在未Mock的错误
-
测试包装器模式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
集成测试超时问题
-
Check what's actually renderingtypescript
render(<Component />); screen.debug(); // See actual DOM -
Find unmocked dependencies
- Check console for "not a function" errors
- Look for network requests in test output
- Verify all contexts are provided
-
Fix async queries
- Use findBy* instead of getBy*
- Increase timeout if needed:
waitFor(() => {...}, { timeout: 3000 }) - Mock React Query properly
-
Simplify component tree
- Test widgets individually first
- Add full integration tests last
- Use data-testid for complex queries
-
检查实际渲染内容typescript
render(<Component />); screen.debug(); // 查看实际DOM -
查找未Mock的依赖
- 检查控制台是否存在“not a function”类错误
- 在测试输出中查看网络请求
- 验证所有上下文是否已提供
-
修复异步查询问题
- 使用findBy替代getBy
- 必要时增加超时时间:
waitFor(() => {...}, { timeout: 3000 }) - 正确Mock React Query
-
简化组件树
- 先单独测试各个小组件
- 最后添加完整集成测试
- 对复杂查询使用data-testid
Performance Optimization
性能优化
Dashboard Load Budget
仪表盘加载预算
| Phase | Target |
|---|---|
| Skeleton render | 0-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
常见误区
- Spinners for fast loads - Use skeletons instead
- Unmemoized expensive computations - Wrap in useMemo
- Testing implementation details - Test user behavior
- Mocking too much - Mock at boundaries only
- Synchronous test expectations - Everything is async
When debugging test timeouts, ALWAYS start with to see what actually rendered.
screen.debug()- 为快速加载内容显示动画 - 改用骨架屏
- 未记忆化的昂贵计算 - 使用useMemo包裹
- 测试实现细节 - 测试用户行为而非内部实现
- 过度Mock - 仅在边界层进行Mock
- 同步测试预期 - 所有操作均为异步
调试测试超时问题时,务必从开始,查看实际渲染内容。
screen.debug()