Back to React tutorials
Advanced15 min read

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

Get In Touch


Ready to discuss your next project? Drop me a message.