Back to blog
Web Platform 6 min read15 July 2026

Speculation Rules API: The Declarative Way to Make Navigations Feel Instant

Every click still costs 200-800ms of blank-screen time. The Speculation Rules API lets browsers prerender the next page before the click happens — here's what it does and where it goes wrong.

Speculation Rules API Performance Prerendering Web Platform Chrome
H

Hanuman Singh

Founder & Lead Engineer · Hanuman Software Services

The problem: every click still costs a round trip

Even on a fast connection, clicking a link triggers a real chain of work — DNS if needed, TCP/TLS, request, server processing, response, parse, render. On a typical marketing or content site that's 200-800ms of blank or loading-state screen per navigation, multiplied by every link a user clicks in a session. Client-side routing in an SPA hides this after the first load, but the very first navigation — and any full page load — still pays it in full.

The Speculation Rules API is the modern, declarative answer: a JSON block that tells the browser which URLs are worth prefetching or fully prerendering before the user clicks, so that by the time they do, the page is already sitting there ready to swap in.

Prefetch vs. prerender — genuinely different things

These two modes get used interchangeably in casual conversation, but the API treats them as distinct with very different costs:

ModeWhat happensCostNavigation feel
PrefetchDownloads the HTML response onlyLow — one requestFaster, but still parses/renders on click
PrerenderFully loads and renders the page in a hidden background tab, including running its JSHigh — a full page load's worth of CPU/networkNear-instant — it's a tab swap, not a load

Prerender is the dramatic one: the target page is actually rendered, off-screen, before the click happens. When the user does click, Chrome activates the already-rendered document instead of starting a new navigation. Done well, this is the difference between a visible loading state and what feels like an instant, client-side-routed transition — on a plain server-rendered page, with no SPA framework involved.

What the rules actually look like

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

eagerness is the important dial: immediate fires as soon as the rule is seen, eager fires on hover/pointerdown, moderate waits for a longer hover, and conservative waits until the user has essentially committed (pointerdown). For prerender specifically, more eager settings mean speculative work happens more often for clicks that never come — that tradeoff is the entire tuning problem.

Where this goes wrong

The API is simple to turn on and easy to misuse. The failure modes we've actually hit:

  • Prerendering pages with side effects on load. If a page fires an analytics pageview, increments a view counter, or calls any non-idempotent endpoint on load, prerendering it fires that side effect for every speculative render — including ones the user never actually visits. The Speculation Rules spec accounts for this with a documented "prerendering" page-visibility state your code can check, but only if you actually check it.
  • Prerendering behind auth or personalization checks. A prerendered page runs in a real browsing context, so if it does a client-side auth check or fetches personalized data, that happens during the speculative render too — and if the user never clicks, you've done that work for nothing. Cap eagerness on any page with real per-request cost.
  • Over-prerendering on mobile. Prerender is a genuinely resource-heavy operation — full JS execution, full render — and Chrome imposes real limits (typically capping concurrent prerenders and disabling more eager modes under memory pressure or data-saver settings), but you can still waste real user battery and data with an overly broad href_matches pattern that fires on every link on a content-heavy page.

How to check it's actually working

Chrome DevTools' Application panel has a dedicated Speculative loads section under Background services — it shows which URLs were prefetched or prerendered, their status, and why a speculation was or wasn't used (a "not used" reason here is often the fastest way to debug a rule that isn't firing the way you expect). Check this before assuming your rules are working; a syntax mistake in the JSON block fails silently with no console error.

Should you turn this on now?

Yes, cautiously, for the cheap case first: prefetching your own internal navigation links (blog index → post, product list → product page) is low-risk and broadly safe to ship today. Prerendering is worth it specifically for high-intent, side-effect-free destinations — a pricing page linked from a prominent CTA, the next post in a series — where the near-instant feel is worth the extra resource cost. Start conservative on eagerness, watch the DevTools panel for a week of real traffic, and widen from there rather than guessing at the right scope up front.

Want your site to feel instant?

We audit real navigation patterns before recommending speculation rules — not a blanket "prerender everything" config that quietly wastes bandwidth. Tell us what's slow and we'll tell you honestly whether this is the fix.

Interested in working together?

Free 30-minute discovery call — no commitment.

Book a call