Back to React
React
medium
mid

How would you debug a performance bottleneck in a React app using DevTools?

1) Reproduce with throttling. 2) React DevTools Profiler — record interaction, look at flame graph (slow renders), 'Why did this render', highlight updates for visual fan-out. 3) Chrome Performance panel for main-thread/long-tasks/layout/paint. 4) Identify category: render fan-out, expensive single render, layout thrash, or non-React JS. 5) Targeted fix. 6) Measure delta. Always profile production builds for accurate numbers.

4 min read·~10 min to think through

Cross-link to [[how-do-you-debug-performance-issues-in-react]] for the broader workflow. This question focuses on the DevTools mechanics.

React DevTools Profiler

Setup

  • Use react-devtools extension or standalone app.
  • Profile production build for accurate numbers (dev has Strict Mode + extra checks).

Record

  1. Open Profiler tab.
  2. Click record (●).
  3. Perform the slow interaction.
  4. Stop recording.

Read the flame graph

  • X axis: time.
  • Y axis: component tree depth.
  • Bar width: render duration.
  • Wide bars = slow renders.

Click a commit (top bar) → see what rendered in that commit + duration.

Why did this render

Hover or click a component → "Why did this render?":

  • "Props changed: [a, b]"
  • "Parent component rendered"
  • "Hook changed"
  • "State changed"

Tells you whether the re-render was justified.

Ranked view

Sorts components by render time in each commit. Top of the list = biggest cost.

Highlight updates

Settings → "Highlight updates when components render." Visual borders flash on rendered nodes. Type in an input — should highlight only the input, not the whole page.

Chrome Performance panel

Setup

  • CPU throttle (4x or 6x).
  • Network throttle (Slow 4G).

Record

  1. Start recording.
  2. Reload or perform interaction.
  3. Stop.

Read

  • Main thread row — JS tasks, render, layout, paint.
  • Long Tasks (red triangles) — > 50ms tasks.
  • Bottom-up view — where time went grouped by function.
  • Call tree — hierarchical.

What to look for

  • Long tasks during interaction → INP killer.
  • Style recalc / layout bars after a React commit → DOM work.
  • Garbage collection spikes → memory pressure.
  • Non-React scripts hogging time → third-party.

Performance Monitor

Real-time JS heap, DOM node count, layout/sec. Useful for spotting leaks while you interact.

Memory panel

Heap snapshots; compare to find leaks (see [[you-notice-a-memory-leak-in-a-react-app-how-would-you-debug-and-fix-it]]).

Coverage panel

What CSS/JS is loaded but unused per route. Useful for bundle audits.

Network panel

  • Waterfall of requests.
  • Initiator (which JS chunk requested this).
  • DNS, TCP, TLS phases per request.
  • Cache hits.

Lighthouse

Full-page audit: LCP, FID/INP, CLS, opportunities (render-blocking, image optimization).

Workflow

  1. Get RUM data to know the real-user worst case.
  2. Reproduce the worst case with throttling.
  3. React Profiler first — is it a render issue?
  4. Performance panel — is it browser work or non-React JS?
  5. Form hypothesis — what fix should help?
  6. Apply the fix.
  7. Re-measure in DevTools and RUM.

Common findings

What you seeLikely cause
Many components re-rendering on every interactionContext fan-out or unstable prop refs
One big slow renderHeavy computation in a single component
Long task with style recalcDOM mutation triggering layout
Long task with no React commit nearbyNon-React JS (analytics, parsers)
Memory growing per interactionCleanup missing

Interview framing

"Two main tools. React DevTools Profiler shows component renders, why they happened, and how long — flame graph + 'Why did this render' is your first stop. Highlight Updates visually shows fan-out. Chrome Performance panel shows the main thread: JS tasks, style/layout/paint, long tasks for INP analysis. Performance Monitor for live heap and DOM node count. Memory panel for leaks. Always profile production builds; dev mode lies. Workflow: reproduce with throttling → React Profiler → Performance panel → form hypothesis → apply fix → measure delta in RUM. The output is a categorized fix (render fan-out, expensive render, layout thrash, non-React JS) and a measured improvement."

Follow-up questions

  • Walk through a recent perf bug you debugged.
  • How do you tell render fan-out from a slow single render?
  • What's the role of Performance Monitor?

Common mistakes

  • Profiling dev builds.
  • Stopping at the first slow component without checking why.
  • Ignoring the browser side (style/layout/paint).

Performance considerations

  • The whole topic.

Edge cases

  • Profiler overhead distorting measurements.
  • Strict Mode double-render in dev.
  • Throttling not matching real user devices.

Real-world examples

  • React docs profiling guide, web.dev case studies, Vercel's perf insights.

Senior engineer discussion

Seniors fluidly switch between Profiler and Performance panel, profile production builds, and tie improvements to RUM.

Related questions