All topics
Performanceintermediate

Profiling with React DevTools Profiler

Learn how to use the React DevTools Profiler tab to identify which components render, how often, and why.

The React DevTools browser extension includes a Profiler tab that records a timeline of component renders during an interaction, showing which components rendered, how long each took, and — critically — why each one re-rendered (props changed, state changed, a parent re-rendered, or a context value changed). This turns performance debugging from guesswork into an evidence-based process.

The Profiler is like a stopwatch-and-clipboard-carrying observer at a factory line, recording exactly which stations (components) were active during a specific production run (interaction), how long each one took, and precisely which instruction (prop/state/context change) triggered each station to do work at all — rather than the floor manager just guessing which station is the bottleneck.

Key Concepts

1
Recording a profiling session involves clicking 'record,' performing the interaction you suspect is slow (typing in a search box, opening a modal), then stopping the recording to inspect a flame graph or ranked chart of every component that rendered during that window, each colored by how long it took relative to others in the same commit.
2
A particularly useful feature is the 'why did this render' information available per component per commit, which explicitly names the reason (e.g., 'props changed: onSelect' or 'hook changed'), removing the need to manually reason about reference equality by inspecting code — the tool tells you directly which prop or piece of state triggered the re-render.
3
Interviewers testing performance debugging skills often ask candidates to describe their process for diagnosing a slow interaction — a strong answer starts with the Profiler to gather evidence about which components are actually re-rendering unnecessarily and why, rather than jumping straight to speculative fixes like wrapping everything in React.memo or useMemo without first confirming where the actual cost lies.
React.memouseMemo