v145 · Web APIs · Performance
Enabling Web Applications to understand bimodal performance timings
Chrome 145 adds APIs that let web applications detect when their performance data follows a bimodal distribution — identifying fast cached responses versus slow network fetches — rather than averaging across both populations.
background
Many performance metrics follow a bimodal distribution: a cluster of fast responses (cache hits, warm connections) and a cluster of slow responses (cold fetches, DNS lookup, TCP setup). Averaging both together produces a mean that doesn't represent either experience.
Chrome 145 provides additional timing resolution — including extended Resource Timing fields — that allows applications to programmatically detect bimodal patterns and present separate percentiles for each population, rather than a misleading aggregate.
concepts
-
Bimodal Demo
Collects resource timing entries for a set of repeated fetches, plots the distribution, and applies a simple K-means split to separate the fast and slow populations.
-
Timing Analysis
How to read Resource Timing entries to distinguish cache hits from network fetches, which fields reveal which phase, and how to compute per-population percentiles.
-
Distribution Detector
Run pre-canned or real fetch workloads, draw a live histogram, and let a 2-mean clustering verdict tell you whether the data is bimodal — and therefore whether overall median/p95 are misleading.
-
Cache vs Network
Fetches the same resource repeatedly and classifies each response as memory cache, disk cache, or network using
transferSizeandconnectStart. The dot chart reveals two populations — and why averaging them produces a meaningless metric.
the change
// Resource Timing entry provides phase breakdown
// Use these to separate cache hits from network fetches:
const entries = performance.getEntriesByType('resource');
const fast = [], slow = [];
for (const e of entries) {
// transferSize === 0 → served from cache (memory or disk)
if (e.transferSize === 0 && e.encodedBodySize > 0) {
fast.push(e.duration);
} else {
slow.push(e.duration);
}
}
// Chrome 145 adds more granular timing to distinguish:
// - Memory cache (near 0ms, connectStart === 0)
// - Disk cache (few ms, connectStart === 0)
// - Network (>20ms, full phase breakdown available)
const p50fast = percentile(fast, 0.5);
const p50slow = percentile(slow, 0.5);
console.log('Fast p50:', p50fast, 'Slow p50:', p50slow);