Skip to content
storybook-addon-performance-panel

Metrics reference

All metrics are color-coded using Web Vitals thresholds:

StatusMeaning
🟢 GreenGood — meets targets
🟡 YellowNeeds improvement — may cause issues
🔴 RedPoor — likely causing issues

Key thresholds

Metric🟢 Good🟡 Needs work🔴 Poor
FPS≥5530–55<30
Frame time≤16.67ms16.67–32ms>32ms
Input latency≤16ms16–50ms>50ms
INP≤200ms200–500ms>500ms
CLS<0.10.1–0.25>0.25
TBT<200ms200–600ms>600ms

Frame timing

Measures rendering smoothness using a requestAnimationFrame loop.

Frame timing panel section
MetricWhat it tells you
FPSFrames per second. Target: 60.
Frame timeAverage ms per frame. Target: ≤16.67ms.
Dropped framesFrames exceeding 2× the expected frame time.
Frame jitterSudden spikes in frame time vs. baseline.
Frame stabilityHow consistent frame times are (percentage).

Input responsiveness

Measures interaction latency using the Event Timing API.

Input responsiveness panel section
MetricWhat it tells you
INPInteraction to Next Paint — p98 of worst interactions. A Core Web Vital.
Input latencyTime from pointer event to next animation frame.
FIDFirst Input Delay — latency of the very first interaction.
Paint timeRendering time via double-requestAnimationFrame.
Last interactionMost recent interaction details. Click Inspect to highlight.
Slowest interactionWorst interaction recorded. Click Inspect to highlight.

INP breakdown

Each interaction includes a timing breakdown:

[wait Xms] → [js Xms] → [paint Xms]
  • Wait (input delay) — time before JS starts processing. High values mean the main thread was blocked.
  • JS (processing time) — time in event handlers. High values mean expensive handler logic.
  • Paint (presentation delay) — time from handler completion to visual update. High values mean expensive rendering.

Main thread health

Detects main thread blocking via the Long Tasks API.

Main thread panel section
MetricWhat it tells you
Long tasksTasks blocking the main thread for >50ms.
Total blocking timeSum of (duration − 50ms) for all long tasks. Matches Lighthouse TBT.
ThrashingStyle writes followed by long frames (forced synchronous layout).
DOM churnRate of DOM mutations per measurement period.

Long animation frames

Detailed frame attribution via the Long Animation Frames API. Chrome 123+ and Edge 123+ only.

Long animation frames panel section
MetricWhat it tells you
LoAF countAnimation frames exceeding 50ms.
Blocking durationTotal and longest blocking time from LoAFs.
P95 duration95th percentile LoAF duration.
Script attributionWhich scripts caused slow frames — source URL, function name, invoker type.

React performance

Uses the React Profiler API. Only available with the default (React) entry — hidden when using ./universal.

React performance panel section
MetricWhat it tells you
Mount count and durationHow many times components mounted and how long each took.
Slow updatesReact updates exceeding the 16ms frame budget.
P95 duration95th percentile update time — worst-case experience.
Render cascadessetState during the commit phase (useLayoutEffect). Very expensive.

Layout stability

CLS measurement via the Layout Instability API with session windowing per the Web Vitals specification.

Layout stability panel section
MetricWhat it tells you
CLSCumulative Layout Shift score. A Core Web Vital.
Forced reflowsLayout reads after style writes, forcing synchronous layout.
Style writesInline style mutations observed via MutationObserver.

Memory and resources

JS heap introspection via performance.memory. Chrome only.

Memory panel section
MetricWhat it tells you
Heap usageCurrent JS heap size.
Memory deltaChange from baseline since last reset.
GC pressureAllocation rate in MB/s. High = frequent garbage collection.
Compositor layersElements promoted to GPU layers.

Element timing

Tracks render timing for elements with the elementtiming attribute via the Element Timing API.

Element timing panel section
MetricWhat it tells you
Element countNumber of tracked elements on the page.
Largest render timeSlowest element to render (similar to LCP).
Individual elementsRender time for each tracked element.

Usage

<img src="/hero.jpg" elementtiming="hero-image" />
<div elementtiming="main-content">Key content</div>
Navigation