Frontend Development › UI Frameworks & Components
Unnecessary Re-renders
Renders that change nothing, and how to avoid them.
Also known as: unnecessary re-renders, extra renders, re-render performance, wasted renders, React re-rendering
A component re-renders when its state changes, when its parent re-renders, or when a context it reads changes. A re-render is unnecessary when the result is identical to last time. Most are harmless: React is fast, and rendering is cheap. They matter when they happen often, on big trees, or with expensive work, and the UI becomes sluggish.
Common causes
- State kept too high. State in
Appchanges on every keystroke, and re-renders the entire app. - A parent re-renders, so all its children do too, even with the same props.
- New object, array or function props created inline every render, which defeats memoization (memoization).
- A frequently changing context value re-renders every consumer (context).
- Expensive computation during render, repeated each time.
- Rendering huge lists in full (list virtualization).
Finding them
- React DevTools Profiler: record an interaction and see which components rendered, why, and how long they took.
- “Highlight updates when components render” shows flashing borders around components as they re-render.
- Add a temporary
console.login a suspect component. - Browser performance panels show long tasks (long tasks).
Measure before changing anything, since you might be fixing something that isn’t slow.
Fixes, in order of preference
- Move state down to the smallest component that uses it. The rest of the tree stops re-rendering.
// Typing re-renders only SearchBox, not the whole page
function Page() { return <><SearchBox /><ExpensiveChart /></>; }
- Lift content up with composition: pass heavy parts as
children, so they aren’t re-created when the wrapper’s state changes. - Memoize the components, values and functions that are actually expensive (
memo,useMemo,useCallback). - Split contexts, or use selectors in a store library, so components subscribe only to what they need.
- Virtualize long lists, and paginate.
- Debounce rapid inputs (debounce).
Remember
Don’t optimize speculatively. Re-rendering isn’t a bug in itself, and sprinkling memo everywhere can make code harder to read without making it faster. Look for the slow interaction first, then find which renders cause it.