The fastest page load is one that has already happened by the time the user clicks. The Speculation Rules API lets a document tell the browser which links the user is likely to follow next, so the browser can fetch them, or fully render them in a hidden tab, before the click. You declare this in a JSON block in the HTML. There is no service worker to register, no caching layer to maintain, and no script to run. The catch is support: as of 2026 it works in Chromium-based browsers and is not something you can assume elsewhere, so it has to be treated as a progressive enhancement.

Browser Support, Stated Plainly

The API is available in Chrome and Edge from version 109, and Chrome added document rules, the where syntax used below, in version 121. Firefox does not support it. Safari has an implementation behind a flag in recent releases, but it is not enabled by default. MDN still labels the API as experimental with limited availability, meaning it is not part of Baseline.

That does not make it unusable. It means the benefit goes to the share of your visitors on Chromium browsers, and everyone else gets the same site they get today. Browsers that do not recognize a <script type="speculationrules"> block ignore it, so there is nothing to break. If you need to detect support in script, HTMLScriptElement.supports("speculationrules") returns whether the browser understands the type.

Prefetch and Prerender

The API offers two actions with very different costs.

Prefetch downloads the response body of the next document and keeps it in an in-memory cache, without fetching its subresources. MDN notes the cache expires after about five minutes. It is cheap and low risk.

Prerender fetches the page, loads its subresources, and renders it in an invisible tab, running its JavaScript. When the user navigates, the browser swaps the prerendered page in, which is why the result can feel instant. It costs far more bandwidth, memory, and CPU, and by default it is limited to same-origin pages.

The guidance in MDN and the Chrome documentation agrees: prefetch liberally, prerender conservatively.

Writing the Rules

A minimal rule set for a content site prefetches same-site links when a pointer hovers over them:

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

The where clause is a document rule: it matches links that are actually on the page, rather than a list you maintain by hand. Combine conditions with and, or, and not, and match either by URL pattern (href_matches) or by CSS selector (selector_matches). The eagerness setting controls when the browser acts. Per the Chrome documentation, on desktop moderate speculates after a 200 millisecond hover, eager after a 10 millisecond hover, and conservative on pointer or touch down. immediate speculates as soon as the rules are parsed. The default is immediate for explicit URL lists and conservative for document rules.

To prerender, exclude anything with side effects and opt individual links out with a class:

<script type="speculationrules">
{
  "prerender": [
    {
      "where": {
        "and": [
          { "href_matches": "/*" },
          { "not": { "href_matches": "/logout" } },
          { "not": { "selector_matches": ".no-prerender" } }
        ]
      },
      "eagerness": "conservative"
    }
  ]
}
</script>

You can also serve rules from a file instead of inline, using the Speculation-Rules response header with a URL. The file must be served with the application/speculationrules+json MIME type. If your site uses a Content Security Policy, inline rules need 'inline-speculation-rules' in script-src, or a nonce or hash.

Chrome caps how much it will do. With immediate eagerness the limits are 50 prefetches and 10 prerenders; with the other levels, only the two most recent speculations stay active, and newer ones displace older ones. Chrome also skips speculation entirely when Save-Data is on, when Energy Saver is active on low battery, when the user has turned off preloading, and for background tabs. You cannot force it, which is one more reason to treat the feature as an enhancement.

Making Prerendering Safe

A prerendered page runs your code before anyone has seen it, and that is where problems start.

URLs with side effects. MDN lists sign-out links, language switches, add-to-cart URLs, and sign-in flows as unsafe to speculate on. Any GET request that changes server state will change it on speculation. Exclude those paths in your rules, and have the server check for the Sec-Purpose request header, which is prefetch for prefetches and prefetch;prerender for prerenders, so it can decline to do work on speculative requests.

Analytics and impressions. A page view logged during prerender counts a visit that may never happen. Delay it until activation:

function whenActivated(fn) {
  if (document.prerendering) {
    document.addEventListener("prerenderingchange", fn, { once: true });
  } else {
    fn();
  }
}

whenActivated(() => sendPageview());

Stale state. When a request changes state, such as logout or a cart update, MDN recommends sending Clear-Site-Data: "prefetchCache", "prerenderCache" so later navigations do not use an out-of-date speculation.

To confirm it works, test with Chromium DevTools. In script, performance.getEntriesByType("navigation")[0].activationStart is greater than zero for a page that was prerendered.

How It Compares With Older Approaches

<link rel="prefetch"> needs a hand-written URL for every page and fetches only the document. MDN describes the Speculation Rules API as superseding the deprecated <link rel="prerender"> and as a better alternative to rel="prefetch". A service worker can also cache pages ahead of time, but it needs registration, a cache strategy, and invalidation logic that you own. Speculation rules need none of that, and they do not replace the service worker’s other jobs, such as offline support.

A sensible rollout for a mostly static content site: add the moderate prefetch rule site-wide, exclude state-changing paths, make your analytics prerender-aware, then consider prerender for a few high-probability links such as the next step in a flow. Measure real-user navigation timings before and after, and keep the rules small. The audience on Firefox and Safari sees no change, and the Chromium audience gets navigations that often feel instantaneous.