v150 · Performance

Pagehide Beacon

The collection pattern the explainer demonstrates: register a pagehide handler that calls performance.getSpeculations() and sends the report with fetch(…, {keepalive:true}). Because pagehide can also mean entry into the back/forward cache, the real handler records event.persisted so analytics can distinguish that case from a final lifecycle end.

The handler is registered for real on pagehide. Building a non-empty payload needs performance.getSpeculations() behind --enable-blink-features=SpeculationMeasurement (or --enable-experimental-web-platform-features) or the origin trial. Without it, the payload is empty and clearly marked — never filled with fake speculation data.
TODO (server route): a production build would POST to an analytics collector. This demo builds the real payload and previews the exact fetch(…, {keepalive:true}) call that would send it to /v150/speculative-load-measurement/collect — a route that still needs wiring in server.ts (respond 204). The request is not fired here so the page stays free of dead-route errors; the payload and call options shown are the real ones.

Handler registered on pagehide. getSpeculations(): checking…

Beacon payload preview

Press “Run the pagehide handler now” to build the payload.

const COLLECT = '/analytics/unused-speculations';

function reportSpeculations(event) {
  if (typeof performance.getSpeculations !== 'function') return;   // feature-detect
  const { preloads, navigations } = performance.getSpeculations();
  // pagehide also fires on BFCache entry; preserve that context.
  const body = JSON.stringify({ preloads, navigations,
    pagehidePersisted: event.persisted });
  // keepalive lets the request outlive the page being dismissed:
  fetch(COLLECT, { method: 'POST', keepalive: true,
    headers: { 'Content-Type': 'application/json' }, body });
}

// The explainer uses pagehide; event.persisted identifies BFCache entry.
window.addEventListener('pagehide', reportSpeculations);

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗