React Performance Optimization Patterns

By Matthew Lanier

React Performance Optimization Patterns

React makes building dynamic user interfaces straightforward, but with that simplicity comes the responsibility of managing performance. I've optimized countless React applications, and the patterns are surprisingly consistent.

Measuring Before Optimizing

The first rule: measure before you optimize. Chrome DevTools' React Profiler is invaluable. It shows:

- Which components are re-rendering - How long renders take - What triggered the re-render

Often, the performance bottleneck isn't where you think it is. Profiling prevents wasted effort on premature optimization.

Component Memoization

`React.memo` prevents unnecessary re-renders when props haven't changed:

const UserCard = React.memo(({ user, onSelect }) => (
  <div onClick={() => onSelect(user)}>
    {user.name}
  </div>
));

But be careful—memoization adds overhead. Use it selectively for components that re-render frequently with the same props.

useMemo and useCallback

These hooks are useful for expensive computations or when passing functions to memoized children:

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);

However, don't memoize everything. The cost of the hook itself can exceed the benefit. Profile first.

Code Splitting and Lazy Loading

For large applications, bundle size becomes an issue. React's `lazy()` and Suspense enable code splitting:

```javascript const HeavyComponent = React.lazy(() => import('./HeavyComponent'));

}> ```

Split at route boundaries for maximum impact. Users only download code they need.

Virtual Lists

If you're rendering thousands of items, virtualization is essential. Libraries like `react-window` render only visible items:

<FixedSizeList
  height={600}
  itemCount={1000}
  itemSize={35}
>
  {Row}
</FixedSizeList>

This transforms rendering 1000 items from milliseconds to microseconds.

Key Takeaways

1. Profile your application first 2. Memoize selectively, not everywhere 3. Split code at route boundaries 4. Virtualize long lists 5. Monitor bundle size in your CI/CD pipeline

Performance optimization is an ongoing process. Make it part of your development workflow from day one.