skip to content

Typing into a filter input on a React screen feels sluggish. Walk through how you would use the React DevTools Profiler to locate the cause rather than guessing at it.

level: seniorimportance: must knowfreq 58%

answer

  1. measure first, change second
  2. enable the reasons before recording
  3. count the commits per keystroke
  4. ranked for depth, flamegraph for breadth
  5. re-record the same interaction to prove it

basics

~20 s

Record the typing with the Profiler, with "record why each component rendered" enabled. Count the commits per keystroke, open the worst one, use Ranked to check for a hot component and Flamegraph for a wide cascade, read the reason on the highest re-rendering component, then re-record after the fix.

solid answer

~50 s

First I make the profile match the complaint: open the Profiler tab, enable **record why each component rendered** before recording, hit record, type a handful of characters at normal speed, and stop. Then I read the commit bar chart — how many commits did one keystroke produce, and how tall are they? That alone often explains the feel. I select the worst commit and check **Ranked**: if one component dominates, the problem is inside it. If the list is flat, I switch to **Flamegraph** and look at how much of the tree is coloured versus greyed, walk to the highest coloured component, and read its recorded render reason — that is where the update entered, and everything below it usually just says the parent rendered. Component filters, especially hiding host DOM elements, make both charts readable on a wide tree. Then I make one change, record the same interaction again, and compare commit counts and durations — the second profile is the evidence, not my intuition.

go deeper

for a junior

Be able to say you would open the Profiler tab, record while reproducing the interaction, and click the tallest commit bar to see which components rendered, rather than guessing at the cause.

for a middle

Explain the two chart readings — a hot component in Ranked versus a wide cascade in Flamegraph — and know that render reasons must be enabled before the recording, not after.

for a senior

Demonstrate the full loop under real conditions: scope the recording to the interaction, use component filters to make the charts readable, fix at the entry point of the cascade, and produce a second profile as evidence.

for a principal

Own the stopping rule and the reporting. Say how you decide render work is no longer the dominant cost, and how you make a claim a reviewer can verify without trusting one engineer's machine.

## Why a workflow question Interviewers ask this because performance work is where engineers most often optimise by folklore. The answer they want is a repeatable procedure with a measurement at the start and a measurement at the end. The tool detail matters less than the discipline. ## Step 1 — reproduce it under the recorder Open React DevTools, go to the **Profiler** tab. Before recording, enable the Profiler setting that records **why each component rendered** — it can only capture that data during the recording, so switching it on afterwards does nothing for a profile you already took. Start recording, then perform exactly the interaction that feels bad: type several characters into the filter at a natural speed. Stop. Keep it short — a few seconds of profile is easier to read than thirty, and the same commits repeat anyway. If the complaint were about the *initial* load of the screen rather than typing, the equivalent is the Profiler's **reload and start profiling** action, which restarts the page with recording already active so mount work is captured. Typing is an update, so plain record is right here. ## Step 2 — read the commit chart before anything else The bar chart across the top is one bar per commit. Two questions: - **How many commits per keystroke?** One is expected. Several per character means each keystroke is triggering multiple rounds of state updates, and the total the user feels is their sum — a finding in itself, independent of any single commit's duration. - **How tall are they?** A run of uniformly expensive commits during typing is the shape that produces "sluggish". ## Step 3 — dissect the worst commit Select the tallest bar and look at both projections of it: - **Ranked** lists only the components that rendered, sorted by their own render time. If one entry towers over the rest, you are done looking: the cost is inside that component and you go read its code. - **Flamegraph** keeps the tree, draws non-rendering components greyed, and sizes each bar by the component *plus its subtree*. If Ranked was flat, this is the view that matters: the ratio of coloured to grey tells you how much of the screen participated in a keystroke. ## Step 4 — find the entry point, not the symptom In the Flamegraph, walk **up** to the highest coloured component and select it. With the reasons recorded, its panel names why it rendered. That component is where the update entered the tree; the components beneath it will typically report that their parent rendered, which makes them consequences rather than causes. Optimising the bottom of a cascade is the most common wasted afternoon in React performance work. ## Step 5 — make the charts readable On a real application both charts are unusable at first because of sheer volume. DevTools component filters help: hiding host DOM elements collapses the tree to your own components, and filtering by name or location removes library wrappers you cannot change anyway. Filters apply to the Profiler charts as well as the Components tree, so the profile becomes a view of code you own. Just remember the chart is now a filtered view. ## Step 6 — change one thing, then re-record Make a single change, repeat the exact same interaction under the recorder, and compare: commits per keystroke, worst commit duration, and the number of rows in the Ranked chart. That last one is often the cleanest before/after number, because it counts components rendered rather than milliseconds measured on your machine. And treat the durations comparatively. They come from a development build on a developer machine, so the honest claim is "this interaction now commits four components instead of four hundred", not "this screen is now 40 ms faster for users". ## Step 7 — know when to stop Stop when the profile no longer shows React render work as the dominant cost of the interaction. At that point further render optimisation buys nothing, and if the screen still feels slow the cause is somewhere the React Profiler does not measure. Saying that out loud is a strong signal in an interview: the tool has a scope, and part of using it well is recognising when the answer is not inside it.

  • The screen is slow to appear on first load rather than while typing. What changes in this workflow?
    You cannot capture mount work by pressing record after the page has loaded, so you use the Profiler's reload-and-start-profiling action, which restarts the page with recording already active. The reading then shifts: the interesting commits are the first ones, and most components will report that they were rendering for the first time, so render reasons matter less than sheer volume and self time.
  • Every component in the worst commit reports that its parent rendered. What is your next move?
    Go up. That reason means those components are downstream of something else, so I walk to the highest component in the coloured region — the one whose reason is anything other than the parent — and work from there. It is the entry point of the update, and it is the only level where a change reduces how much of the tree ends up in the commit.
  • How do you present the result so a reviewer can check your claim?
    With two profiles of the identical interaction, before and after, taken on the same machine with the same DevTools settings, and a comparison of concrete counts: commits per keystroke, worst commit duration, and how many components appear in the Ranked chart. Counts travel better than millisecond figures, since the numbers come from a development build on my machine.

saying these in an interview costs you the question

  • Starts changing code before recording anything
  • Records the whole session instead of the interaction that feels slow
  • Optimises the deepest components in the cascade rather than the top
  • Never re-records to confirm the change helped
  • Quotes development-build milliseconds as user-facing numbers

context