No matter how much you optimize, there's a hard limit: pages can only start loading after the user clicks. You're stuck waiting for DNS lookups, server responses, and rendering - even on a fast site, that's hundreds of milliseconds.
But what if the browser could predict where the user's going next and start loading that page before they click? That's what Chrome's Speculation Rules API does. You can achieve 0ms load times - the page just appears.
Understanding Prefetch vs Prerender
The Speculation Rules API gives you two strategies:
Prefetching downloads just the HTML document. When the user clicks, the browser has a head start but still needs to fetch CSS, JS, and images.
Prerendering goes all-in - it loads everything in a hidden background tab, executes JavaScript, and renders the full page. When the user clicks, the browser just swaps tabs. Instant. No loading screen.
This is the modern replacement for the old <link rel="prerender"> tags (which were deprecated due to privacy issues). The new API is smarter and gives you way more control.
Why This Matters: Perceived Performance
Just because you get a perfect Lighthouse score - doesn't always mean that your site feels fast. Even optimized pages need DNS lookup, TCP handshake, TLS negotiation, server response, and rendering. That's hundreds of milliseconds minimum.
Speculation rules eliminate perceived wait time by working during the user's decision-making. When someone hovers over a link for 200ms, you can use that time to pre-load or pre-render the destination. By the time they click, the work's done.
The benefits:
- Zero white flash between pages
- Instant interactions: JS already parsed and executed
- Better Core Web Vitals: LCP often hits 0ms for prerendered pages
- Profit?...give it a try! It feels like actual magic.
Implementing Speculation Rules
Speculation rules are defined in a <script type="speculationrules"> tag with a JSON configuration. Let's look at practical examples for different use cases.
Example 1: Conservative Prerender (Safest)
Prerender when a user starts clicking. This version uses exclusions to prevent the browser from accidentally triggering background actions:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout" } }
]
},
"eagerness": "conservative"
}
]
}
</script>
Why the not rules? Some links trigger actions just by being visited (like logging out or adding an item to a cart via a URL). Since prerendering "visits" the page in a hidden tab, we exclude these paths to prevent the browser from accidentally logging the user out or changing their cart state while they are just browsing.
Example 2: Moderate Prerender (Recommended Starting Point)
Prerender on 200ms hover—balances performance and resource cost. This is the simplest catch-all for general content pages:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "moderate"
}
]
}
</script>
Example 3: Prefetch Specific Pages, Prerender on Hover
Eagerly prefetch your most important pages on page load, then prerender any link the user hovers over:
<script type="speculationrules">
{
"prefetch": [
{
"urls": [
"/products",
"/pricing",
"/docs"
],
"eagerness": "eager"
}
],
"prerender": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "moderate"
}
]
}
</script>
Example 4: Privacy-Preserving Cross-Origin Prefetch
Prefetch external links with privacy protections. The anonymous-client-ip-when-cross-origin flag uses Chrome's private prefetch proxy to hide the user's IP address:
<script type="speculationrules">
{
"prefetch": [
{
"urls": [
"https://example.com/article",
"https://partner-site.com/page"
],
"requires": [
"anonymous-client-ip-when-cross-origin"
],
"referrer_policy": "no-referrer"
}
]
}
</script>
Example 5: CSS Selector-Based Rules
Prerender only links with specific classes:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"selector_matches": ".prerender-this"
},
"eagerness": "eager"
}
],
"prefetch": [
{
"where": {
"selector_matches": ".prefetch-this"
},
"eagerness": "moderate"
}
]
}
</script>
Example 6: Blog with Article Navigation
Prefetch the next/previous article links immediately, prerender related articles on hover:
<script type="speculationrules">
{
"prefetch": [
{
"where": {
"selector_matches": ".pagination-link"
},
"eagerness": "immediate"
}
],
"prerender": [
{
"where": {
"and": [
{ "selector_matches": ".related-article" },
{ "href_matches": "/blog/*" }
]
},
"eagerness": "moderate"
}
]
}
</script>
Example 7: E-commerce Product Pages
Prefetch category pages, prerender product pages, but exclude cart and checkout:
<script type="speculationrules">
{
"prefetch": [
{
"where": {
"href_matches": "/category/*"
},
"eagerness": "eager"
}
],
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/product/*" },
{ "not": { "href_matches": "/cart" } },
{ "not": { "href_matches": "/checkout" } },
{ "not": { "href_matches": "*?add-to-cart=*" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
Example 8: Documentation Site with Search Parameters
Prerender doc pages but exclude search results and dynamic filters:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/docs/*" },
{ "not": { "href_matches": "*\\?*" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
Example 9: Multi-Language Site
Prerender pages in the current language, prefetch language switcher links:
<script type="speculationrules">
{
"prefetch": [
{
"where": {
"selector_matches": ".language-switcher a"
},
"eagerness": "conservative"
}
],
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/en/*" },
{ "not": { "selector_matches": ".language-switcher a" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
Example 10: SPA-Style Navigation
Aggressively prerender all internal navigation while excluding external links and auth flows:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/login" } },
{ "not": { "href_matches": "/logout" } },
{ "not": { "href_matches": "/api/*" } },
{ "not": { "href_matches": "https://*" } },
{
"where": { "selector_matches": ".prefetch-this" },
"eagerness": "moderate"
}
]
}
</script>
Choosing Your Eagerness Level
The eagerness setting controls when speculation happens:
-
Conservative - Triggers on
pointerdown(mousedown/touchstart). Minimal waste, minimal gain. Safe starting point. -
Moderate - Desktop: 200ms hover or
pointerdown. Mobile: viewport heuristics. Recommended for most sites. Used by Google Search. - Eager - 10ms hover on desktop (Chrome 141+). Aggressive but user-initiated. Good for high-traffic pages.
- Immediate - Prerenders as soon as the rule loads. High waste if users don't click. Only for high-confidence predictions (pagination, primary CTA).
Browser Support: Can You Use It?
The Speculation Rules API is Chromium-only but works as Progressive Enhancement: unsupported browsers just ignore the script tag.
| Browser | Support | Notes |
|---|---|---|
| Chrome / Edge | ✅ Full | Supported since Chrome 109 / Edge 109 (January 2023). |
| Brave / Opera | ✅ Full | Full support via the Chromium engine. |
| Safari | 🟡 Behind Flag | Available in Safari 26.2+ behind a flag (not enabled by default). |
| Firefox | ❌ No | Currently does not support the Speculation Rules API. |
Important Guardrails
Prerendering uses bandwidth and battery, so Chrome includes smart protections to prevent abuse:
- Resource Limits: Chrome caps concurrent prerenders - up to 50 immediate/eager prefetches (mobile), 10 prerenders, and 2 moderate/conservative prerenders (FIFO). When you hit the limit, old prerenders are canceled.
- Deferred APIs: Intrusive APIs (Camera, Microphone, Notifications, Geolocation) don't activate until the user actually views the page.
- Respects User Settings: Prerendering won't run if the user has Data Saver, Energy Saver, or has disabled "Preload pages" in settings.
- Cross-origin iframes: Third-party iframes don't load during prerender - they wait until activation. This prevents tracking and reduces resource waste.
Final Thoughts
I'm honestly surprised I hadn't heard about this sooner. Now that all major Chromium browsers support the API, it's definitely worth using. It's easy to get caught up in complex performance optimizations and overlook the simpler wins - like how proper semantic HTML improves SEO, or how vanilla CSS can outperform heavy frameworks. The Speculation Rules API fits right into that category in my book: powerful, straightforward, and built into the platform. I can't wait to keep experimenting with this and see how far it can go.
Further Reading
- Prerender pages in Chrome - Complete API reference
- Implementation guide for complex sites - Advanced patterns and best practices
- Debugging speculation rules - DevTools guide
- How Google Search uses speculation rules - Real-world implementation and results
- MDN: Speculation Rules API - Web standards documentation
Top comments (1)
This is super cool, I’ve gotta try it on my blog and pets! Very well written as well!