--- name: reactive-dashboard-performance description: Expert in building blazing-fast reactive dashboards with comprehensive testing. Masters React performance patterns, testing strategies for async components, and real-world patterns from Linear, Vercel, Notion. allowed-tools: - Read - Write - Edit - Bash - Grep - Glob version: 1.0.0 triggers: - dashboard performance - slow tests - reactive testing - integration tests timeout - dashboard optimization metadata: category: Frontend Development tags: - react - performance - testing - dashboard - optimization pairs-with: - skill: react-performance-optimizer reason: Dashboard performance depends on React memoization, virtualization, and state management - skill: admin-dashboard reason: Admin dashboards are the primary consumer of reactive dashboard performance patterns - skill: data-viz-2025 reason: Dashboard charts and graphs require performant data visualization rendering --- # Reactive Dashboard Performance Expert in building production-grade reactive dashboards that load in <100ms and have comprehensive test coverage. ## Core Expertise ### Performance Patterns (Linear, Vercel, Notion-grade) 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 ### 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(); const element = screen.getByText('Welcome'); // RIGHT - waits for async resolution render(); 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 }) => ( {children} ); ``` ### 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 ## Diagnostic Protocol ### Integration Test Timeouts 1. **Check what's actually rendering** ```typescript render(); 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(() => {...}, { 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 ## Performance Optimization ### Dashboard Load Budget | Phase | Target | |-------|--------| | Skeleton render | 0-16ms (1 frame) | | First data paint | <100ms | | Full interactive | <200ms | | Lazy widgets | <500ms | ### React Query Config ```typescript const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5 * 60 * 1000, // 5min cacheTime: 30 * 60 * 1000, // 30min refetchOnWindowFocus: false, refetchOnMount: false, retry: 1, }, }, }); ``` ### Skeleton Pattern ```typescript function Dashboard() { const { data, isLoading } = useQuery('dashboard', fetchDashboard); // Show skeleton immediately, no loading check return (
{data ? : }
); } ``` ## 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.