Skip to main content

Performance Optimization

React is fast by default, but as your application grows, you may encounter performance bottlenecks. This guide covers strategies for identifying and resolving common performance issues.

Production Builds

Always use production builds for deployed applications. Development builds include helpful warnings and debugging tools but are significantly slower.
Production builds enable optimizations like code minification, dead code elimination, and removal of development-only warnings. React’s production build is typically 2-3x faster than development mode.

Avoiding Unnecessary Renders

One of the most common performance issues is components re-rendering when their output hasn’t changed.

Before: Unnecessary Re-renders

After: Optimized with React.memo

Use React DevTools Profiler to identify components that re-render frequently. Focus optimization efforts on components that render slowly or render very often.

React DevTools Profiler

The React DevTools Profiler helps you visualize component render performance.

Using the Profiler

  1. Install React DevTools
  2. Open the Profiler tab
  3. Click the record button
  4. Interact with your app
  5. Stop recording to analyze results

What to Look For

  • Flame graphs: Visualize which components took the longest to render
  • Ranked charts: See components sorted by render time
  • Component charts: Track individual component render counts
  • Yellow/orange bars: Indicate slower renders that may need optimization
See the Profiler documentation for more details.

Common Performance Issues

1. Creating New Objects/Functions in Render

Problem: Creating new object references on every render prevents memoization.
Solution: Use useMemo and useCallback to maintain stable references.
See the Memoization documentation for more details.

2. Large Lists Without Keys

Problem: React can’t efficiently update lists without stable keys.
Solution: Use unique, stable identifiers.

3. Expensive Calculations in Render

Problem: Heavy computations run on every render.
Solution: Memoize expensive calculations.

4. Context Updates Causing Wide Re-renders

Problem: Context updates cause all consumers to re-render.
Solution: Split contexts by update frequency.

PureComponent for Class Components

For class components, extend PureComponent instead of Component for automatic shallow prop comparison (see ReactBaseClasses.js:132).
PureComponent uses shallow comparison. If you pass objects or arrays as props, ensure they have stable references or the comparison will fail and cause unnecessary re-renders.

Code Splitting

Split large bundles using React.lazy() and dynamic imports.

Virtualization for Long Lists

For lists with hundreds or thousands of items, render only visible items.
Use libraries like react-window or react-virtualized for efficient list rendering. These libraries only render items in the viewport, dramatically improving performance for large datasets.

Measuring Performance

Browser DevTools

Use the Performance tab in Chrome DevTools:
  1. Open DevTools (F12)
  2. Go to Performance tab
  3. Click Record
  4. Interact with your app
  5. Stop recording and analyze the flame chart

User Timing API

Optimization Checklist

Don’t optimize prematurely! Always measure first. Premature optimization can make code harder to maintain without meaningful performance gains. Focus on optimizing slow components identified through profiling.
  • Use production builds for deployed apps
  • Profile with React DevTools to identify slow components
  • Memoize expensive calculations with useMemo
  • Memoize callback functions with useCallback
  • Wrap expensive components with React.memo
  • Use stable keys for lists
  • Split large contexts into smaller ones
  • Implement code splitting for large components
  • Virtualize long lists
  • Measure improvements with real user metrics