Topic: Web platform

Speculation Rules: Faster Navigation Must Not Do Things Early

Speculation Rules can speed up the next MPA navigation, but prefetch and prerender have very different costs. Exclude side-effecting URLs, preserve ordinary navigation, then use activation and hit rate to decide whether to expand.

Animated meme (expand/collapse)
Not every link should open early. Keep sign-out, checkout, and state-changing URLs outside speculative loading. · Source: GIPHY

When I first saw the Speculation Rules API, it looked like JSON that could make an entire site fast. Why not preload every internal link?

I now start with a different question: if someone never visits this URL, would loading it early do anything it should not do?

This API targets a future full-document navigation; it does not pre-run API data for an SPA router. A supporting browser can guess the next page, fetch its document, or run the whole page in a hidden environment. The browser can still ignore that hint because of memory, network, or user preferences, so the ordinary click path must always work.

First separate fetching a page from running a page

Action What the browser does early A sensible starting point
prefetch Fetches the target document response body, without its referenced subresources A common, low-cost, predictable next page
prerender Fetches, renders, runs JavaScript, and loads subresources in a hidden page A small set of high-hit-rate pages with handled side effects

The difference is not merely “a little faster” versus “much faster.” A prerender is closer to opening an invisible tab: it spends network, memory, and CPU, and most of that work is wasted when the person never navigates there. By default it is also suited to same-origin documents.

For an ordinary MPA, I would validate the hypothesis with prefetch first. prerender in the API name is not a reason to make it step one.

A GET URL is not automatically safe to guess

Speculation Rules makes a request for a future navigation. If a site hides a state change behind a GET URL, or a page load itself does work, one bad guess can produce a surprising result.

Exclude sign-out, locale switches, add-to-cart, confirmation actions, personalised flows, and similar paths first. This example considers article pages only and explicitly leaves higher-risk paths out:

<script type="speculationrules">
  {
    "prefetch": [
      {
        "where": {
          "and": [
            { "href_matches": "/article/*" },
            { "not": { "href_matches": "/logout" } },
            { "not": { "href_matches": "/checkout/*" } }
          ]
        },
        "eagerness": "moderate"
      }
    ]
  }
</script>

This does not run in every browser, nor does deployment guarantee that every link will be prefetched. It is progressive enhancement for browsers that support it; everyone else still gets ordinary, correct navigation.

If a site has a strict Content Security Policy, this inline JSON script must also be explicitly permitted by script-src, using a hash, nonce, or inline-speculation-rules. That detail is worth checking before celebrating a fast Chrome demo.

Prerender runs JavaScript early; side effects wait for activation

prefetch has a smaller risk surface. prerender lets the page run JavaScript before someone can see it. Custom analytics, ad impressions, local-storage writes, and components rendered from login or cart state all need another review.

Chrome’s implementation guide notes that some services, including Google Analytics, delay until activation already. That is not permission to assume that custom scripts, tag managers, or third-party widgets are safe. Application code should decide explicitly what can run early and what must wait until a person is actually on the page.

function whenActivated() {
  return new Promise((resolve) => {
    if (document.prerendering) {
      document.addEventListener("prerenderingchange", resolve, { once: true });
    } else {
      resolve();
    }
  });
}

async function initSideEffects() {
  await whenActivated();
  initCustomAnalytics();
  refreshCartBadge();
}

void initSideEffects();

Delaying every script is a safe beginning, but not necessarily the end state. Running too much code on activation can move an INP problem to the moment a page looks ready. A better next step is to inspect each task: allow content that can render safely during prerender, and defer work that records, writes, or depends on current state.

Animated meme (expand/collapse)
The celebration belongs to activation of a prepared page. Speculation alone should not count as a visit or conversion. · Source: GIPHY

Measure one or two high-confidence pages first

Good candidates usually have two traits: the next step is predictable, and the page is inexpensive. Think of a list leading to a popular article, a fixed next step in a flow, or one link that someone has clearly hovered. A low-hit-rate, site-wide rule mainly spends a visitor’s bandwidth for them.

I would track three things together:

  • The ratio of speculation requests to real activations, to learn whether the guesses hit.
  • Whether activated pages improve LCP, INP, and navigation time.
  • Whether mobile-network cost, server load, and misses remain acceptable.

Chrome DevTools’ Application → Background services → Speculative loads shows rules, candidate URLs, and failure reasons. That answers whether a rule actually works more reliably than a faster-feeling homepage. The navigation timing entry’s activationStart can also help measure pages that were prerendered before activation.

The Speculation Rules API is not Baseline today. That is not a reason to avoid it, but it is a design reminder: layer it on top of normal navigation, never make it a correctness requirement.

What I learned

  • I treat a fast next page as a document-lifecycle optimisation, not as an SPA route or general resource preload.
  • prefetch tests a user journey first; prerender is for high-confidence pages with no unhandled side effects and a clear activation plan.
  • A speed improvement needs hit rate, interaction metrics, and wasted-resource cost together. One successful demo does not justify enabling it everywhere.

External references