Performance
Measure and optimize React rendering performance with profiling, memoization, and code splitting.
Measure First
React DevTools Profiler records render durations and commit reasons. Chrome Performance tab shows long tasks blocking the main thread. Core Web Vitals (LCP, INP, CLS) measure real user experience — optimize what users feel, not arbitrary metrics.
Establish baselines before optimizing. One slow list on a dashboard used daily matters more than micro-optimizing a settings page visited monthly.
- Profiler for render hotspots
- Core Web Vitals for user experience
- Baseline before optimizing
Render Optimization
React.memo skips rerender when props shallow-equal. useMemo/useCallback stabilize references for memoized children. Split contexts and state to narrow rerender scope.
Virtualize long lists. Defer non-critical updates with startTransition. Avoid inline object/array literals as props to memoized components — they break equality every render.
- React.memo for stable-prop components
- Virtualize long lists
- startTransition for deferrable updates
Code Splitting and Lazy Loading
React.lazy and dynamic import() split bundles loaded on demand. Wrap lazy components in Suspense with meaningful fallbacks. Route-based splitting is the highest ROI — each page loads only its code.
Next.js dynamic imports handle SSR nuances with `{ ssr: false }` for client-only modules. Preload critical routes on hover or viewport entry.
- React.lazy + Suspense per route
- Next.js dynamic() for SSR control
- Preload on interaction
const Chart = lazy(() => import('./Chart'));
<Suspense fallback={<Skeleton />}><Chart /></Suspense>Bundle Size
Analyze bundles with webpack-bundle-analyzer or Next.js built-in analysis. Replace heavy libraries with lighter alternatives. Import specific modules (`import debounce from 'lodash/debounce'`) not entire packages.
Tree shaking removes unused exports — ensure side-effect-free packages and avoid importing CommonJS barrels that defeat shaking.
- Analyze bundle composition
- Import specific modules
- Tree-shake friendly dependencies
Production Checklist
Enable production builds with minification. Serve compressed assets. Use CDN for static files. Image optimization (next/image) reduces LCP. Avoid layout shift with reserved dimensions.
Monitor performance budgets in CI — fail builds when bundle size regresses beyond threshold. Performance is a feature requiring ongoing discipline, not a one-time pass.
- Production builds and compression
- Image optimization for LCP
- Bundle size budgets in CI