demo · v148
Forced Style Flush
The other half of the style timing story is forcedStyleDuration: time spent recalculating style inside an event handler because the script asked for a layout-affecting value. Click "trigger forced flushes" to make the page do exactly that, and watch the LoAF entry separate the natural style time from the forced flush time.
Heads up
Origin trial.
forcedStyleDuration appears alongside styleDuration on
PerformanceLongAnimationFrameTiming. Numbers come from a real
PerformanceObserver below.
styleDuration
—
ms total (style recalc)
forcedStyleDuration
—
ms inside handler
renderDuration
—
ms (paint/layout/etc)
the code
// "Forced flush" = read a layout/style value inside an event handler.
// The browser must update style/layout immediately to answer the read.
button.addEventListener("click", () => {
for (const el of allCells) {
el.classList.toggle("warm"); // queue a style invalidation
const _ = el.offsetWidth; // force style+layout flush right now
}
});
// Observer surfaces the cost of those forced flushes:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log({
styleDuration: entry.styleDuration, // total recalc time
forcedStyleDuration: entry.forcedStyleDuration, // forced subset
renderDuration: entry.renderDuration,
});
}
}).observe({ type: "long-animation-frame", buffered: true });
see also
- Long Animation Frames style duration — feature index
- Style Cost Meter — sibling concept
- W3C Long Animation Frames PR #30
- MDN: PerformanceLongAnimationFrameTiming
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗