v151 · loading · reliability
Why not client-side JavaScript?
The explainer rejects sendBeacon-on-load reporting as unreliable. This page combines real lifecycle events with an explicitly fixed one-activation scenario to show how a naive reporter can drift; it does not establish that this page was itself activated from a prefetch.
Scenario activations (fixed)
1
Naive reporting attempts
0
Tip: switch to another tab and back, or navigate away and press Back, to see the client counter drift.
Real lifecycle events observed
Waiting for page-lifecycle events…
The three failure modes (from the explainer)
- Cache ambiguity — telemetry may filter back/forward navigations to avoid double counting, so later back/forward visits to a page that was originally prefetched can be missed.
- Duplicate reporting — lifecycle handlers can fire again on cache restoration, producing another client report for the same document lifetime.
- Race conditions — the script often does not run early enough to capture rapid transitions, so the signal is lost.
The proposal addresses these failure modes with a one-time, credentialless HEAD request dispatched by the navigation stack after commit, without routing it through the origin's service worker or page script. This page illustrates the client-side problem; it does not verify that server request.
How the naive reporter is wired
// A typical (unreliable) client-side reporter:
addEventListener("pageshow", (e) => {
// fires on bfcache restore too (e.persisted === true) → double count
navigator.sendBeacon("/telemetry/activation");
});
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") navigator.sendBeacon("/telemetry/activation");
});