Performance Optimization Skill
Performance optimization patterns for Next.js applications.
Reference Files:
- bundle-analysis.md - Bundle size optimization
- react-rendering.md - React performance patterns
- database-optimization.md - Query optimization
- examples.md - Practical examples
Performance Philosophy
Principles:
- Measure first - Never optimize without metrics
- Target bottlenecks - Focus on the biggest impact areas
- User-centric - Prioritize perceived performance
- Iterative - Small, measurable improvements
Quick Reference
Bundle Size
# Analyze bundle
npm run analyze
# Targets
# - Total: < 200KB gzipped (first load)
# - Per-route: < 100KB gzipped
Quick Wins:
// Dynamic imports for heavy components
const Chart = dynamic(() => import("./Chart"), { ssr: false });
// Prefer native implementations
const debounce = (fn: Function, ms: number) => {
// ✅ Native
let timeout: NodeJS.Timeout;
return (...args: unknown[]) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), ms);
};
};
React Rendering
// With React Compiler - usually automatic optimization
// Manual memoization only for:
// 1. External library callbacks
const stableHandler = useCallback(() => {}, []);
// 2. Context values
const value = useMemo(() => ({ state, dispatch }), [state]);
// 3. Virtualized lists (50+ items)
import { useVirtualizer } from "@tanstack/react-virtual";
Database Queries
// Always use limits
const query = db.collection("items").where("userId", "==", userId).limit(20);
// Parallel fetching
const [users, posts] = await Promise.all([getUsers(), getPosts()]);
Core Web Vitals
| Metric | Target | Optimization |
|---|---|---|
| LCP | < 2.5s | priority on hero image, preload fonts |
| INP | < 200ms | startTransition, defer non-critical JS |
| CLS | < 0.1 | Fixed dimensions, skeleton loaders |
Performance Targets
Bundle Size Targets
| Category | Target (gzipped) |
|---|---|
| First Load JS | < 100KB |
| Per-page JS | < 50KB |
| Total app | < 300KB |
| Single dependency | < 30KB |
Runtime Targets
| Metric | Good | Needs Work |
|---|---|---|
| Time to Interactive | < 3s | > 5s |
| First Contentful Paint | < 1.8s | > 3s |
| Server Response | < 200ms | > 500ms |
| Database Query | < 100ms | > 500ms |
Analysis Commands
# Bundle analysis
npm run analyze
# Build output
npm run build
# Check .next/static/chunks sizes
# Lighthouse (via Chrome DevTools)
# Performance tab → Lighthouse
# React Profiler
# React DevTools → Profiler tab
Decision Tree
Performance Issue?
│
├─ Slow page load?
│ ├─ Large bundle → Bundle analysis
│ ├─ Slow API → Database optimization
│ └─ Render blocking → Code splitting
│
├─ Slow interactions?
│ ├─ Long lists → Virtualization
│ ├─ Heavy computation → Web Worker / useMemo
│ └─ Frequent re-renders → React Profiler
│
└─ Layout shifts?
├─ Images → Set dimensions
├─ Fonts → Font preloading
└─ Dynamic content → Skeleton loaders
Common Issues & Solutions
| Issue | Detection | Solution |
|---|---|---|
| Large bundle | > 100KB first load | Dynamic imports, tree shaking |
| Slow renders | React Profiler > 16ms | Memoization, virtualization |
| N+1 queries | Multiple sequential DB calls | Batch queries, denormalization |
| Layout shift | CLS > 0.1 | Fixed dimensions, skeletons |
| Unoptimized images | Large image files | next/image, WebP, responsive |
Related Skills
react-19-compiler- React Compiler optimization guidancefirebase-firestore- Database query patternsstructured-logging- Performance logging