HomeJournalThis post

Speculation Rules API: Prerender Without Regret

Classify likely next links through privacy, side-effect, activation, and resource budgets before emitting browser prerender rules.

JP
JP Casabianca
AI Engineer and Product Designer · full-stack delivery · Bogotá

The Speculation Rules API can prepare a likely next page before the click, but only an eligibility policy keeps that speed from becoming a privacy or side-effect bug. This tutorial builds a storefront prerender contract with safe candidates, activation checks, explicit budgets, and a complete ordinary-navigation fallback.

Speculation Rules API begins with safe eligibility

Prerendering asks the browser to prepare a document that the user may navigate to soon. That can shorten the visible work after a click, but preparation may perform network requests, execute script, read storage, or expose a destination to infrastructure. Prediction alone is therefore not enough; every candidate must pass a product policy before rules are emitted.

Start with navigations that are safe GET requests and whose URLs reveal no sensitive intent. Exclude logout, cart mutation, purchases, destructive settings, administration, personalized secrets, and destinations that depend on a single-use token. Also exclude pages whose server or client code incorrectly performs effects merely because a document loaded.

The WHATWG speculative loading section defines the web-platform integration, while the Prerendering Revamped document explains lifecycle considerations. The application remains responsible for deciding which URLs are appropriate candidates.

The local storefront is synthetic and never navigates or measures browser performance. It classifies five generated routes and proves only that mutation and private paths are excluded by the frozen policy.

Navigation probability mapA storefront graph weights likely next pages while mutation, private, and low-confidence routes remain visibly excluded.currentproductcart+collectionaccountdetail
  • Probability is estimated from product intent, not used alone.
  • Mutation and private routes are excluded even when likely.
  • A bounded candidate budget admits only the highest eligible links.
Navigation probability map reading key
SignalInterpretation
Navigation probability mapA storefront graph weights likely next pages while mutation, private, and low-confidence routes remain visibly excluded.
Figure 1: Prediction proposes candidates; eligibility policy decides whether prerender may start.

Map candidate probability without granting permission

Candidate signals can include link prominence, funnel position, recent anonymous aggregate navigation, hover or pointer intent, and explicit product knowledge. Use them to rank already eligible links or to choose when a rule appears. Do not let a high score bypass privacy, authorization, or side-effect constraints.

Keep probabilities coarse and bounded. A storefront may nominate the next product detail from a collection page and a featured collection from the home page. It should not prerender every link in a navigation bar, because resource waste and cache churn can erase any benefit and burden users on constrained networks.

The navigation-probability map separates product links from cart, account, and session-ending routes. The highlighted nodes are not a claim that real users choose them at a measured rate; they visualize an authored policy over a constructed page graph.

The Speculation Rules API should receive a maximum candidate count, allowed destination classes, and a reason code for each admitted link. That receipt makes a future over-eager rule traceable to ranking, eligibility, or budget.

Emit narrow speculationrules JSON

Generate rules from normalized routes rather than concatenating raw selectors or URLs. A route registry can attach speculation metadata such as safeToPrepare, privateIntent, effectRisk, freshnessMode, and resourceClass. The policy selects an action such as prefetch or prerender and emits only the href patterns that survive.

Prefer understandable conditions. Document rules can match links by URL patterns or selectors, but a broad pattern may capture future routes the policy never reviewed. Add negative conditions for known private or mutating areas and test the resulting candidate set against a frozen site map.

Feature detection must preserve normal navigation. If the browser does not support speculation rules or declines a candidate, the anchor should still lead to a fully functional page. The API is an optimization layer, never a requirement for correctness.

The runnable lab serializes its selected links into a small speculationrules-shaped object and exposes the exact receipt. It does not inject live rules, making the safety exercise deterministic while leaving production integration as a deliberate next step.

Keep prepared pages free of irreversible effects

A prerendered document may execute before the user sees it. Page initialization must not mark messages read, consume coupons, start paid work, mutate carts, send presence, or record a conversion. Move effects behind explicit user actions or activation-aware logic, and make server endpoints honor correct HTTP semantics regardless of client behavior.

Analytics needs a lifecycle contract. A page view should normally correspond to an activated user-visible navigation, while preparation may warrant separate operational telemetry. Label events so prerender creation, activation, abandonment, and ordinary navigation cannot be counted as the same conversion.

Third-party scripts deserve special scrutiny because they may not understand speculative lifecycle. Delay unnecessary integrations until activation or exclude pages that cannot run safely without them. The Speculation Rules API cannot repair code that treats document construction as user consent.

Use the service-worker update flow as an adjacent lifecycle example: hidden background work and visible control changes need explicit coordination. Both systems are safest when preparation and commitment are different states.

Privacy and side-effect eligibility sieveCandidate links pass through method, effect, identity, privacy, freshness, and confidence checks before rules are emitted.safe GET navigation?no sensitive URL or identity?activation-correct page?confidence above budget?eligible
  1. Reject state-changing or session-ending destinations.
  2. Reject URLs whose speculative fetch would disclose private intent.
  3. Require pages that behave correctly before and after activation.
  4. Apply a candidate and resource budget last.
Privacy and side-effect eligibility sieve reading key
SignalInterpretation
Privacy and side-effect eligibility sieveCandidate links pass through method, effect, identity, privacy, freshness, and confidence checks before rules are emitted.
Figure 2: Safety and privacy are hard filters; likelihood ranks only the survivors.

Runnable artifact — The browser lab classifies a frozen storefront route set, emits a bounded rules receipt, and performs no live speculative navigation.

<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Speculation policy lab</title><style>body{font:16px system-ui;max-width:760px;margin:2rem auto;padding:1rem;background:#f4efe7;color:#17202a}button{padding:.7rem 1rem}li{margin:.55rem 0}.yes{color:#17643a}.no{color:#9b2c2c}</style><h1>Speculation policy lab</h1><p>Classify generated storefront links; no network navigation occurs.</p><button id="run">Run policy</button><ul id="routes"></ul><output id="receipt" aria-live="polite"></output><script>const links=[{href:"/products/linen-lamp",p:.82,effect:false,private:false},{href:"/cart/add?id=7",p:.71,effect:true,private:false},{href:"/account/orders",p:.64,effect:false,private:true},{href:"/collections/new",p:.57,effect:false,private:false},{href:"/logout",p:.31,effect:true,private:true}];const classify=x=>x.p>=.55&&!x.effect&&!x.private;function run(){routes.innerHTML=links.map(x=>'<li class="'+(classify(x)?'yes':'no')+'">'+x.href+' — '+(classify(x)?'eligible':'excluded')+'</li>').join('');const selected=links.filter(classify).map(x=>x.href);const rules={prerender:[{where:{href_matches:selected}}]};receipt.value=selected.join(',')==='/products/linen-lamp,/collections/new'?'PASS: policy excludes effects and private routes':'FAIL';receipt.dataset.rules=JSON.stringify(rules)}run.onclick=run;run()</script></html>

Design the prerender activation boundary

Activation turns a prepared document into the visible page. Reconcile focus, visibility-dependent subscriptions, scroll restoration, analytics, stale data, and any state that changed after preparation began. The page should not briefly show a private or outdated state before those checks complete.

Treat time-sensitive data as a revalidation problem. A product price or stock count prepared seconds earlier may need a lightweight refresh at activation, while stable layout and code can remain warm. Decide which fields may render stale temporarily and which must block an action until verified.

Navigation events and history behavior should match ordinary visits. The Navigation API comparison helps separate app-level transitions from browser lifecycle. Test back/forward navigation, same-document anchors, focus order, screen-reader announcements, and interrupted activation.

The cold-versus-prerender figure is a conceptual timeline, not a latency measurement. Its purpose is to make the commit point visible: irreversible work belongs after the user-visible navigation or behind another explicit action.

Budget network, memory, and freshness

Prerender can download and execute much more than prefetch. Set budgets by connection hints, device capability, page weight, candidate confidence, and current application state. A user with data saving enabled or a memory-constrained device should keep ordinary navigation without penalty.

Limit simultaneous candidates and remove obsolete rules when context changes. If a user filters a collection, the previously likely product may no longer deserve preparation. Give candidate records an expiry and a source page state so stale predictions can be revoked.

Measure bytes prepared, abandonment, activation rate, error rate, memory pressure where observable, and user-facing navigation timing for eligible cohorts. The HTTP 103 Early Hints article offers a different early-loading tool for stable critical resources; do not combine optimizations without attributing their effects.

The Speculation Rules API should have a global kill switch and conservative defaults. If telemetry disappears or error rates rise, stop adding rules rather than leaving speculative work invisible to operators.

Test the failure matrix before rollout

Exercise unsupported browsers, supported browsers that decline prerender, abandoned candidates, rapid candidate changes, activation after authentication changes, stale product data, service-worker updates, offline state, script error during preparation, and navigation to an excluded route. Verify that every case retains correct ordinary navigation.

Automate route-policy tests from the site map. Each mutating, private, or single-use route should be a negative fixture; each eligible route should state why it is safe and how activation revalidates it. A new route without speculation metadata should default to excluded.

Use browser automation for lifecycle behavior and server logs for request semantics, but label synthetic and production evidence separately. The local lab proves policy classification only. It does not establish an LCP improvement, activation success rate, or cross-browser support result.

Keep those evidence classes visibly separate.

The frontend observability guide can host the field contract. Add preparation and activation dimensions without including sensitive destination queries or user identity.

Cold load versus prerender activationTwo navigation timelines separate speculative work, activation, deferred analytics, and user-visible effects.cold: click → request → parse → renderprerender: prepare → click → activateactivation boundary
PhaseRule
Prepareno irreversible user-visible effect
Activatereconcile visibility, focus, analytics, and stale data
Fallbackordinary navigation remains complete
Cold load versus prerender activation reading key
SignalInterpretation
Cold load versus prerender activationTwo navigation timelines separate speculative work, activation, deferred analytics, and user-visible effects.
Figure 3: A faster activation is valid only when the prepared page preserves navigation semantics.

Roll out prerender as a reversible product feature

Begin with one stable, public, high-confidence destination class and a small cohort. Compare ordinary and eligible navigations while watching errors, abandonment, bytes, and activation correctness. Expand only after the effect-free and privacy invariants hold in field traces.

Keep the rule generator, eligible route registry, and browser integration versioned. A review should show the exact URLs or patterns added and the negative tests that still pass. Rollback should remove speculation rules without requiring a site architecture change.

The Speculation Rules API earns its place when preparation is invisible except for a faster correct navigation. It fails when the product counts abandoned pages, exposes private routes, consumes resources broadly, or makes the fallback a second-class experience.

Open the policy lab, inspect why each generated route is included or excluded, and replace the examples with five routes from your product. Do not emit live prerender rules until every admitted route has an activation and side-effect owner.

Keep the rollout language exact: browser prerender is the preparation mode, navigation prefetch is a smaller alternative, speculationrules JSON is the declared input, and prerender activation is the commit boundary. In the synthetic matrix, the Speculation Rules API admits only public effect-free routes and records every exclusion. Add an operator view that lists current candidates, expiry, source page state, and kill-switch status without exposing private URLs. The Speculation Rules API stays disabled whenever that operational receipt is missing or stale.