Lesson 74 of 80
The Profiler tab turns 'I think this component re-renders too much' from a guess into something you can actually see and prove.
15 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Every other lesson on rendering and memoization has you reasoning about why a component re-renders by reading code. The React DevTools Profiler's flamegraph shows you what actually happened, per commit, for real — instead of predicting it. You record a session, interact with the app, and stop recording; the flamegraph then shows one bar per component that rendered during a chosen commit, with the bar's width and color both telling you something.
Width is proportional to how long that component took to render in that specific commit. Color tells you whether it rendered at all: gray means the component did not render during this commit (React bailed out — usually because of React.memo or because its props/state genuinely didn't change), while yellow/orange shades mean it rendered, with darker/warmer meaning slower relative to everything else in that commit.
function App() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount((c) => c + 1)}>{count}</button>
<ExpensiveList items={staticItems} />
</div>
);
}
staticItems never changes, so ExpensiveList never has a real reason to re-render when the button is clicked — but as written, it will anyway, because App re-rendering re-runs ExpensiveList's render by default. Here's how you'd actually confirm that with the Profiler instead of just suspecting it:
ExpensiveList shows up with a colored bar — it rendered — even though nothing it actually displays changed.ExpensiveList's bar. It reports the reason: the parent (App) re-rendered, and ExpensiveList has no memoization to bail out with.const ExpensiveList = React.memo(function ExpensiveList({ items }) { ... }).ExpensiveList now shows up gray — it didn't render this commit at all. React compared its props (items, still the same reference), found them equal, and skipped it entirely.That gray-vs-colored difference, before and after, is the direct, visual version of what the memoization lesson describes in prose: a stable reference reaching a component wrapped in React.memo lets React skip the render outright.
Every bar in this flamegraph is a direct visualization of two things covered earlier: reconciliation deciding a component needs to re-render, and memoization deciding whether that render can be skipped. The colored-versus-gray difference on ExpensiveList before and after wrapping it in React.memo isn't a new mechanism — it's the exact mechanism from those lessons, just rendered as a picture instead of something you have to trace through code in your head.