Browser DevTools Performance Panel
Record main-thread timelines: long tasks, style/layout/paint, frames, and how to turn flame charts into INP fixes.
- browser
- devtools
- performance
- main-thread
The Performance panel answers: what occupied the main thread while the user waited? Lighthouse scores guess; a recording shows Recalculate Style, Layout, Paint, Evaluate Script, and long tasks.
Docs: Chrome Performance panel, Analyze runtime performance.
Capture a useful profile
- Enable Screenshots and Web Vitals markers when available.
- Start recording → reproduce the jank (click, type, scroll) → stop.
- Prefer a short focused interaction over a 30s mess.
- CPU 4× slowdown surfaces issues mid-tier phones feel.
Cold-load profiles differ from interaction profiles. For INP, record the actual click/tap path, not only initial load.
Anatomy
| Region | Meaning |
|---|---|
| Frames / FPS | Dropped frames = jank |
| Main track | Tasks on the main thread |
| Network | Resources aligned in time |
| Timings | FCP, LCP when instrumented |
| Bottom-up / Call tree | Aggregated JS cost |
| Event log | Ordered events |
Long tasks (> ~50ms) block input and paint. Yellow/red bars are first suspects for poor INP.
Forced layout in the flame chart
// Bad: read geometry after writes in a loop
items.forEach((el) => {
el.style.width = el.offsetWidth + 10 + 'px';
});
You will see Recalculate Style → Layout inside a loop. Fix: batch reads, then batch writes (or animate transform). See Avoiding layout thrashing.
Attribution for interactions
- Find the Event (click) on the main track.
- Measure input delay (main thread busy before handler).
- Measure handler duration.
- Measure presentation delay until next paint.
That maps to INP: delay → processing → next paint. See Event Timing for INP.
Marks you control
performance.mark('filter:start');
expensiveFilter(data);
performance.mark('filter:end');
performance.measure('filter', 'filter:start', 'filter:end');
Custom measures show up in the timeline and help separate framework cost from your code.
Filmstrip
Screenshots show when the UI actually changed. A long script with no visual update still hurts INP if it delays the next paint after input.
Workflow
- Reproduce with throttling.
- Identify longest tasks.
- Expand stacks to your functions first.
- Fix or yield; re-record.
- Confirm field metrics move — lab is directional.
Performance panel is not a heap snapshot; use Memory for leaks. GC pauses can appear as long tasks when allocation is wild.
Interview out-loud
“I record Performance, reproduce the interaction, find long tasks and forced layout, then split work or remove thrashing. Load-only Lighthouse doesn’t explain mid-session INP.”
Reading a click that “feels dead”
- Arm CPU 4× slowdown; start recording.
- Click the control once; wait for UI; stop.
- Find the Event: click — note the long task before
processingStartif present (input delay). - Expand the handler stack — is it your code or a third-party?
- Check whether the next paint occurs only after a massive style/layout on a large tree.
If the flame chart shows layout thrash, fix thrashing before micro-optimizing React memo. If it shows a 200ms third-party tag, gate the tag. Re-record after each change; don’t stack five “optimizations” without evidence.
Related
Further depth
Teams often under-invest in this topic until an incident or CWV regression. Schedule a one-hour drill: reproduce the failure mode in DevTools, list the top three mitigations for your stack, and file tickets with owners. Revisit after the next major feature that touches networking, rendering, auth, or third parties — those are the moments regressions land. Keep primary documentation links in the runbook so on-call is not searching chat history at 2am.
Concrete artifacts to leave behind: a short architecture note, a CI assertion or header snapshot, and a dashboard panel (lab or field) that would have caught the last bug. Teaching the rest of the team the mental model matters as much as the one-line fix.
Further reading
Related guides
- Browser DevTools Network PanelRead waterfalls, timing phases, headers, throttling, and initiator chains in the Network panel like a production debugger.
- Long Tasks APIDetect main-thread tasks over 50ms with PerformanceObserver longtask entries and fix INP-killing work.
- Main Thread vs Compositor ThreadWhat runs on the main thread vs compositor, why scroll can be smooth while clicks feel dead, and fix strategies.
- Memory Profiling BasicsHeap snapshots, allocation timelines, detached DOM nodes, and practical leak hunts in SPAs.
- Throttling CPU and NetworkDevTools CPU and network throttling: when lab numbers lie, custom profiles, and reproducing field pain.