6 min read
0%

React DevTools Profiler

Back to Blog
React DevTools Profiler

React DevTools Profiler

The React DevTools Profiler records render timing for every component across an interaction. It’s the primary tool for finding what’s slow and why.

Setup

Install the React DevTools browser extension for Chrome or Firefox. Open DevTools → “Profiler” tab.

Recording a Profile

  1. Click the record button (circle) in the Profiler panel
  2. Perform the interaction you want to measure (click, type, navigate)
  3. Click stop

The Profiler shows a flamegraph of every render that occurred during the recording.

Reading the Flamegraph

Each bar represents a component. Width represents render time. Color encodes relative cost:

  • Gray — component did not render during this commit
  • Blue/Green — rendered (faster)
  • Yellow/Red — rendered (slower, relative to others in the commit)
App                  [===========] 12ms
  Header             [==] 2ms
  Dashboard          [===========] 10ms
    ExpensiveChart   [=========] 9ms   ← bottleneck
    SidePanel        [] 0.5ms

Click any bar to see why it rendered.

“Why Did This Render?”

Enable “Record why each component rendered” in Profiler settings. For each rendered component, the panel shows:

  • Props changed — which specific props changed
  • State changed — which state hook triggered the update
  • Context changed — which context value changed
  • Parent re-rendered — parent re-rendered but this component had no own changes

Ranked Chart

Switch to Ranked view. Components are sorted by render duration — slowest at top. Useful for quickly finding the single most expensive component without navigating the tree.

Commit Timeline

The top bar shows each commit (a batch of DOM updates) as a circle. Taller = longer. Click a circle to inspect that commit’s component tree.

What to Look For

Components that render too often:

  • Same component appearing across many commits
  • Renders where “parent re-rendered” is the only reason (not using its own state/context)
  • Fix: wrap in React.memo

Expensive renders:

  • Wide bars in the flamegraph
  • Heavy computation during render (sorting, filtering large arrays)
  • Fix: useMemo for the computation, virtualization for long lists

Cascade re-renders:

  • One state change causes unrelated subtrees to re-render
  • Fix: colocate state, split context, add selectors

Profiling Production Builds

DevTools Profiler is stripped from production builds by default. To profile production:

// vite.config.js
resolve: {
  alias: {
    'react-dom': 'react-dom/profiling',
  }
}

Canvas is not supported in your browser