v145 · Web APIs · Bimodal Demo
Bimodal Demo
Collects resource timing data for repeated fetches, uses transferSize to split cache hits from network fetches, and shows separate statistics for each population.
This demo fetches the page stylesheet multiple times. The first fetch is a network request; subsequent fetches come from the browser cache. Resource Timing's
transferSize field reveals which population each measurement belongs to, exposing the bimodal distribution.
distribution
Click “Run demo” to collect data.
Fetches collected—
Fast (cached) — count—
Fast — p50 duration—
Fast — p95 duration—
Slow (network) — count—
Slow — p50 duration—
Overall mean (misleading)—
code
function percentile(sorted, p) {
if (!sorted.length) return NaN;
const i = Math.floor(p * (sorted.length - 1));
return sorted[i];
}
async function collectTimings(url, n = 20) {
// Clear buffered entries
performance.clearResourceTimings();
for (let i = 0; i < n; i++) {
// cache: 'no-store' for first, default for rest to allow caching
await fetch(url, { cache: i === 0 ? 'no-store' : 'default' });
}
const entries = performance.getEntriesByName(url);
const fast = [], slow = [];
for (const e of entries) {
// transferSize=0 + encodedBodySize>0 → cache hit
if (e.transferSize === 0 && e.encodedBodySize > 0) {
fast.push(e.duration);
} else {
slow.push(e.duration);
}
}
fast.sort((a, b) => a - b);
slow.sort((a, b) => a - b);
return { fast, slow };
}