Profiling and Measuring
AdvancedTwo different questions need two different tools: "which component is slow" is the React Profiler, "is the page slow for users" is Lighthouse and field metrics.
Overview
Frontend performance splits into rendering cost inside React and load performance in the browser, and people frequently answer one question with the other tool. A component that re-renders twenty times per keystroke is a React Profiler problem. A page that takes four seconds to become interactive is usually a bundle and network problem that no amount of memoisation touches. Knowing which you have — and being able to say so with a number rather than an impression — is what makes a performance conversation productive.
The React Profiler
Record an interaction and read the two numbers that matter.
// React DevTools -> Profiler -> record -> interact -> stop
// The flame chart shows, per commit:
// - which components rendered
// - actual duration (this component and its children)
// - self duration (this component alone)
// - WHY it rendered, with "Record why each component rendered" on
// Read it in this order:
// 1. How many commits did one interaction cause? Several is a
// cascade — usually chained effects or state set during render.
// 2. Which component has the largest self duration?
// 3. Why did it render — props, state, hooks, or parent?
// The Profiler API for production measurements
<Profiler id="ProblemList" onRender={(id, phase, actual, base) => {
if (actual > 16) analytics.track('slow_render', { id, phase, actual })
}}>
// 16ms is one frame at 60fps. Anything longer drops a frame.
// Always confirm in a production build: development React is far
// slower, and StrictMode doubles the render count.Load Performance
The user-facing metrics, and which fix belongs to which.
// Lighthouse, or better, real user data from the field:
// LCP largest contentful paint < 2.5s "when did I see it"
// INP interaction to next paint < 200ms "did it respond"
// CLS cumulative layout shift < 0.1 "did it move"
// Cause -> fix, by metric:
// LCP bundle size, render-blocking CSS/JS, unoptimised hero image
// -> code splitting, preload the hero, server rendering
// INP long tasks blocking the main thread
// -> break up work, defer non-urgent updates, virtualise
// CLS images and ads without reserved space, late-loading fonts
// -> width/height on images, font-display: swap, skeletons
// Measure in the field, not only on your machine
new PerformanceObserver(list => {
for (const e of list.getEntries()) send('lcp', e.startTime)
}).observe({ type: 'largest-contentful-paint', buffered: true })
// A React app's LCP is usually decided by bundle size and by whether
// the shell renders before data arrives — not by component code.Bundle Analysis
The first thing to check on a slow-loading React app.
npx vite-bundle-visualizer
ANALYZE=true npm run build # Next, with @next/bundle-analyzer
npx source-map-explorer 'dist/**/*.js'
// The usual findings, in order of frequency:
// - a chart or editor library on the critical path -> lazy import
// - an icon set imported as a barrel -> import per icon
// - moment or a full lodash -> Intl, date-fns, native
// - two copies of React from a linked package -> npm ls react
// - a locale bundle including 200 languages -> configure the plugin
// Set a budget and fail CI when the initial chunk grows past it.
// Bundles regress one merge at a time, and nobody notices until the
// number is embarrassing.
// Then the React-specific wins: route splitting, deferring below
// the fold, and not shipping admin code to logged-out visitors.Key Points to Remember
- 1The React Profiler answers "which component is slow"; Lighthouse and field metrics answer "is the page slow"
- 2Read a profile as: how many commits, largest self duration, and why did it render
- 3A frame is 16ms — renders longer than that drop frames and show up as INP
- 4Verify in a production build, since development React is slower and StrictMode doubles renders
- 5For a slow-loading app, analyse the bundle first — the cause is usually one oversized dependency on the critical path
Interview Questions
Sign in to ask AriaHow do you decide whether a performance problem is rendering or loading?
What do LCP, INP and CLS measure, and what typically causes each?
Why must profiling conclusions be verified in a production build?
Ask Aria about Profiling and Measuring
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.