Performance optimization in React is one of the most important aspects of building scalable applications. In this article, we'll dive deep into the key techniques that will help you create fast and responsive user interfaces.

Understanding Re-renders

Before we start optimizing, it's crucial to understand when and why React components re-render. A component re-renders when:

  • Its state changes
  • Its props change
  • Its parent component re-renders

React.memo

React.memo is a higher-order component that memoizes your component. It prevents re-renders if the props haven't changed:

const ExpensiveComponent = React.memo(({ data }) => {
  // Only re-renders when 'data' actually changes
  return <div>{processExpensiveData(data)}</div>;
});
Tip: Use React.memo for components that render often with the same props.

useMemo Hook

The useMemo hook memoizes computed values, preventing expensive calculations on every render:

const sortedItems = useMemo(() => {
  return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);

useCallback Hook

useCallback memoizes functions, which is especially useful when passing callbacks to child components:

const handleClick = useCallback((id) => {
  setSelectedId(id);
}, []);

When to use useCallback?

  • When passing functions to memoized child components
  • When the function is a dependency of other hooks
  • For event handlers in lists with many items

Virtualization

For long lists, consider using virtualization libraries like react-window or react-virtualized. These render only visible items, dramatically improving performance:

import { FixedSizeList } from 'react-window';

<FixedSizeList
  height={400}
  itemCount={10000}
  itemSize={35}
>
  {Row}
</FixedSizeList>

Conclusion

Performance optimization is a balance between code complexity and actual performance gains. Always measure before optimizing, and focus on the parts that truly impact user experience.

Back to Blog