demo · v142 · performance
Transition Performance Lab
Click any tile to trigger a real view transition. A live performance panel measures every transition with performance.measure() and a PerformanceObserver watches for paint entries. The stress-test fires five transitions in rapid succession — watch the concurrent-guard skip the queued ones.
not supported
document.activeViewTransition is not available in this browser. The demo still runs
using a plain DOM swap but the concurrent-guard and the activeViewTransition readout
won't function — upgrade to Chrome 142+ to see the real behaviour.
Live performance panel
Last duration
—
Avg duration
—
activeViewTransition
null
Transitions run
0
Skipped (guard)
0
Paint entries
0
Last stress batch — completed:—
Skipped:—
How it works
Each click calls document.startViewTransition(). Before calling it we check document.activeViewTransition — if it's non-null a transition is still in flight and we skip, logging the guard action. performance.mark() / performance.measure() wrap the transition so we capture real wall-clock duration. A PerformanceObserver watching paint entries counts how many paint events fire during the sequence.
Code
// Concurrent guard + performance measurement
async function safeTransition(updateFn, label) {
if (document.activeViewTransition) {
console.log(`${label}: skipped — transition in flight`);
return;
}
performance.mark(`vt-start-${label}`);
const vt = document.startViewTransition(updateFn);
// poll activeViewTransition until it clears
const poll = () => {
if (document.activeViewTransition) requestAnimationFrame(poll);
};
requestAnimationFrame(poll);
await vt.finished;
performance.mark(`vt-end-${label}`);
performance.measure(`vt-${label}`, `vt-start-${label}`, `vt-end-${label}`);
const [entry] = performance.getEntriesByName(`vt-${label}`);
console.log(`${label}: ${entry.duration.toFixed(1)} ms`);
}