Implementing Speculative Loading (Speculation Rules API) for Your Website
Speculation Rules API is a browser mechanism for prefetch and prerender pages before the user clicks a link. It enables instant navigation on supported browsers.
Difference from Classic Prefetch
Classic <link rel="prefetch"> loads the HTML document into the cache. Prerender via Speculation Rules goes further — the browser actually renders the page in a hidden tab, including JS execution, subresource loading, and DOM tree construction. When the user navigates, they see an already-prepared page.
Support: Chrome 109+, Edge 109+. Firefox and Safari — prefetch only, no prerender.
Basic Configuration
<script type="speculationrules">
{
"prerender": [
{
"where": { "href_matches": "/product/*" },
"eagerness": "moderate"
}
],
"prefetch": [
{
"where": { "href_matches": "/*" },
"eagerness": "conservative"
}
]
}
</script>
Eagerness Levels
| Value | Trigger | Usage |
|---|---|---|
immediate |
Upon parsing | High-priority pages |
eager |
Minimal interaction | Main CTAs |
moderate |
Hover 200ms | Navigation |
conservative |
Mousedown/touchstart | All internal links |
Document Rules vs List Rules
List Rules — explicit URL list:
{
"prerender": [
{ "urls": ["/checkout", "/cart"] }
]
}
Document Rules — rules based on href patterns:
{
"prefetch": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/admin/*" } },
{ "not": { "href_matches": "*.pdf" } }
]
}
}
]
}
Dynamic Management via JS
// Programmatically add speculative loading rules
const script = document.createElement('script')
script.type = 'speculationrules'
script.text = JSON.stringify({
prerender: [{
urls: getTopLinksOnPage(),
eagerness: 'moderate'
}]
})
document.head.appendChild(script)
Limitations and Considerations
- Server analytics — prerender initiates a real HTTP request. GA4 and Plausible handle this correctly via Activation API (page becomes active only on actual navigation), but server-side counters may inflate
-
Authenticated requests — prerender doesn't work for pages with
Cache-Control: no-store - Mutating side-effects — pages that charge money or send emails on load should not be prerendered
- Limit — browser limits concurrent prerender (typically 2 pages)
Verification
Chrome DevTools → Application → Speculation Rules shows status for each rule. document.prerendering — true if the page is currently being speculatively rendered.
document.addEventListener('prerenderingchange', () => {
if (!document.prerendering) {
// page activated — can initialize analytics
initAnalytics()
}
})
Timeline
Basic setup for a static website — 1 day. Integration with dynamic rules and analytics consideration — 2–3 days.







