React performance is one of the most over-optimised areas in frontend development. Developers reach for useMemo and useCallback before they've even identified a problem. Here's what actually matters.
Measure first
Open the React DevTools Profiler. Record an interaction. Find the components that are slow. Everything else is guesswork. Optimise based on data, not intuition.
Virtualise long lists
Rendering 500 list items into the DOM is slow, regardless of framework. Libraries like react-virtual or @tanstack/virtual render only the items in the viewport. This is the single biggest win for data-heavy UIs.
Code split at the route level
Every page shouldn't ship every component. Use React.lazy and Suspense at the route level to split your bundle. Users on the home page don't need the dashboard code.
`useMemo` and `useCallback` are often wrong
These hooks have a cost — memory allocation, dependency comparison on every render. They only pay off when the computation they memoize is genuinely expensive or when referential stability is required (e.g. a dependency of useEffect). Wrapping a string concatenation in useMemo is slower than just doing the concatenation.
State colocation beats global state
State that lives as high as possible causes as many re-renders as possible. Keep state as close to where it's used as possible. A form's input state belongs in the form, not in a global store.