# Performance Checklist Quick reference checklist for web application performance. Use alongside the `performance-optimization` skill. ## Core Web Vitals Targets | Metric | Good | Needs Work | Poor | |--------|------|------------|------| | LCP (Largest Contentful Paint) | ≤ 2.5s | ≤ 4.0s | > 4.0s | | INP (Interaction to Next Paint) | ≤ 200ms | ≤ 500ms | > 500ms | | CLS (Cumulative Layout Shift) | ≤ 0.1 | ≤ 0.25 | > 0.25 | ## Frontend Checklist ### Images - [ ] Images use modern formats (WebP, AVIF) - [ ] Images are responsively sized (`srcset` and `sizes`) - [ ] Images have explicit `width` and `height` attributes (prevents CLS) - [ ] Below-the-fold images use `loading="lazy"` - [ ] Hero/LCP images use `fetchpriority="high"` and no lazy loading ### JavaScript - [ ] Bundle size under 200KB gzipped (initial load) - [ ] Code splitting with dynamic `import()` for routes and heavy features - [ ] Tree shaking enabled (no dead code in production bundle) - [ ] No blocking JavaScript in `` (use `defer` or `async`) - [ ] Heavy computation offloaded to Web Workers (if applicable) - [ ] `React.memo()` on expensive components that re-render with same props - [ ] `useMemo()` / `useCallback()` only where profiling shows benefit ### CSS - [ ] Critical CSS inlined or preloaded - [ ] No render-blocking CSS for non-critical styles - [ ] No CSS-in-JS runtime cost in production (use extraction) - [ ] Font display strategy set (`font-display: swap` or `optional`) - [ ] System font stack considered before custom fonts ### Network - [ ] Static assets cached with long `max-age` + content hashing - [ ] API responses cached where appropriate (`Cache-Control`) - [ ] HTTP/2 or HTTP/3 enabled - [ ] Resources preconnected (``) for known origins - [ ] No unnecessary redirects ### Rendering - [ ] No layout thrashing (forced synchronous layouts) - [ ] Animations use `transform` and `opacity` (GPU-accelerated) - [ ] Long lists use virtualization (e.g., `react-window`) - [ ] No unnecessary full-page re-renders ## Backend Checklist ### Database - [ ] No N+1 query patterns (use eager loading / joins) - [ ] Queries have appropriate indexes - [ ] List endpoints paginated (never `SELECT * FROM table`) - [ ] Connection pooling configured - [ ] Slow query logging enabled ### API - [ ] Response times < 200ms (p95) - [ ] No synchronous heavy computation in request handlers - [ ] Bulk operations instead of loops of individual calls - [ ] Response compression (gzip/brotli) - [ ] Appropriate caching (in-memory, Redis, CDN) ### Infrastructure - [ ] CDN for static assets - [ ] Server located close to users (or edge deployment) - [ ] Horizontal scaling configured (if needed) - [ ] Health check endpoint for load balancer ## Measurement Commands ```bash # Lighthouse CLI npx lighthouse https://localhost:3000 --output json --output-path ./report.json # Bundle analysis npx webpack-bundle-analyzer stats.json # or for Vite: npx vite-bundle-visualizer # Check bundle size npx bundlesize # Web Vitals in code import { onLCP, onINP, onCLS } from 'web-vitals'; onLCP(console.log); onINP(console.log); onCLS(console.log); ``` ## Common Anti-Patterns | Anti-Pattern | Impact | Fix | |---|---|---| | N+1 queries | Linear DB load growth | Use joins, includes, or batch loading | | Unbounded queries | Memory exhaustion, timeouts | Always paginate, add LIMIT | | Missing indexes | Slow reads as data grows | Add indexes for filtered/sorted columns | | Layout thrashing | Jank, dropped frames | Batch DOM reads, then batch writes | | Unoptimized images | Slow LCP, wasted bandwidth | Use WebP, responsive sizes, lazy load | | Large bundles | Slow Time to Interactive | Code split, tree shake, audit deps | | Blocking main thread | Poor INP, unresponsive UI | Use Web Workers, defer work | | Memory leaks | Growing memory, eventual crash | Clean up listeners, intervals, refs |