- React
- Performance Engineering, Profiling, and Virtualization
- React DevTools Profiler: Flamegraph Analysis
React DevTools Profiler: Flamegraph Analysis
The React DevTools Profiler records render passes to diagnose performance bottlenecks. The Flamegraph view shows component tree render durations (width = duration, color = cost), while the "Why did this render?" setting pinpoints specific prop or state changes.
Key Learning Objectives
Interpret Flamegraph charts and Ranked charts in React DevTools Profiler.
Enable "Record why each component rendered" to identify prop and hook changes.
Differentiate between actual duration (time rendering this commit) and base duration (time to render without memoization).
Use the programmatic <Profiler id onRender={callback}> API for production telemetry.
The Interview Problem & Context
Explain how to use the React DevTools Profiler to diagnose why a component is re-rendering. What is the difference between "actual duration" and "base duration"?
1import React, { Profiler, ProfilerOnRenderCallback } from 'react';23const onRenderCallback: ProfilerOnRenderCallback = (4 id, // the "id" prop of the Profiler tree that just committed5 phase, // "mount" or "update"6 actualDuration, // time spent rendering the committed update7 baseDuration, // estimated time to render the entire subtree without memoization8 startTime, // when React began rendering this update9 commitTime // when React committed this update10) => {11 if (actualDuration > 16) {12 // Flag dropped frames (> 16ms / 60fps threshold) to telemetry service13 console.warn(`[Slow Render] ${id} (${phase}): ${actualDuration.toFixed(2)}ms`);14 }15};1617export function AppWithProfiler() {18 return (19 <Profiler id="AppRoot" onRender={onRenderCallback}>20 <MainApplication />21 </Profiler>22 );23}
Deep Architectural Explanation
Profiling React Applications
When diagnosing performance issues, never guess. Use the React DevTools Profiler.
1. Flamegraph View
- Each bar represents a component.
- Bar Width: Indicates how long the component (and its children) took to render.
- Bar Color:
- Gray: The component did not render during this commit!
- Teal / Blue: Rendered fast.
- Yellow: Took the longest time to render in this commit pass.
2. Actual Duration vs Base Duration
actualDuration: The actual time spent rendering the component in the current commit. If memoized and unchanged, this is close to zero.baseDuration: How long it would take to render the entire subtree from scratch without any memoization. It represents worst-case rendering cost.
3. Identifying Re-render Causes
In DevTools Settings -> Profiler:
- Check "Record why each component rendered while profiling".
- Clicking any component in the Flamegraph reveals:
- "Props changed: [onClick, user]"
- "State changed: [count]"
- "Parent component rendered"
Common Interview Traps & Pitfalls
Profiling in development mode where React code is 3-5x slower due to debug checks and warning overhead.
Optimizing components with small actual durations (< 1ms) while ignoring yellow bottlenecks (> 50ms).
Leaving programmatic <Profiler> hooks active in high-traffic production environments without sampling.
Senior Interviewer Follow-Up Probes
How do you build a Next.js production build with profiling enabled (--profile)?
How does Interaction Tracing correlate user clicks with render commits in the profiler?
What are the limitations of the programmatic onRender callback?
Frequently Asked Interview Questions
Why should you always profile on production builds?
Development builds contain extra warning checks, validation, and unminified code that is 3x to 10x slower, distorting performance measurements.
What does "actual duration" measure in the profiler?
The exact amount of time React spent rendering that component during the specific recorded commit pass.
What does a gray component bar in the Flamegraph mean?
It means the component did not render at all during that commit pass (it was successfully memoized or untouched).
How do you find why a component re-rendered in DevTools?
Enable "Record why each component rendered" in Profiler settings; clicking on any rendered bar will list the specific changed props, state, or context.
