Imagine a world where your website feels like a local native app. No loading spinners, no white flashes, just instant transitions. For a long time, we relied on <link rel="prefetch"> or <link rel="prerender">, but these were blunt instruments. Today, I want to show you how to implement Speculation Rules API, the modern way to tell the browser exactly which pages to prepare in the background based on real user intent.
In my experience testing this on several production sites, the shift from simple prefetching to full prerendering can make the perceived load time feel like zero milliseconds. This is a massive win for your core web vitals optimization guide 2026 goals, specifically impacting Largest Contentful Paint (LCP) and Interaction to Next Paint (INP).
Prerequisites
- A basic understanding of JSON and how to inject script tags into HTML.
- A modern Chromium-based browser (Chrome 121+).
- Access to a site where you can modify the HTML head or inject JavaScript.
- Knowledge of your site’s most common navigation paths (which links are clicked most?).
Step-by-Step Implementation
Step 1: Understanding the JSON Structure
Unlike the old link tags, the Speculation Rules API uses a JSON object inside a <script type="speculationrules"> tag. The browser parses this JSON and decides when to trigger the fetch or render. The most common rule is the document_url rule, which targets specific URLs.
<script type="speculationrules">
{
"prerender": [
{ "source": "list", "urls": [ "/about", "/contact", "/pricing" ] }
]
}
</script>
Step 2: Implementing Dynamic Rules based on User Intent
Hardcoding links is fine for a small site, but for a blog or e-commerce store, you want to be smarter. I’ve found that implementing a “hover-to-prerender” strategy is the most efficient use of bandwidth. Instead of prerendering everything, we only prerender when a user hovers over a link for more than 200ms.
Here is how I implement this via JavaScript:
function addSpeculationRule(url) {
const specScript = document.createElement('script');
specScript.type = 'speculationrules';
const specRules = {
prerender: [{
source: 'list',
urls: [url]
}]
};
specScript.textContent = JSON.stringify(specRules);
document.head.appendChild(specScript);
}
// Apply to all links with a specific data attribute
document.querySelectorAll('a[data-speculate]').forEach(link => {
let hoverTimer;
link.addEventListener('mouseenter', () => {
hoverTimer = setTimeout(() => {
addSpeculationRule(link.href);
}, 200);
});
link.addEventListener('mouseleave', () => clearTimeout(hoverTimer));
});
Step 3: Using Document Rules for Patterns
If you have a predictable URL structure (like /blog/post-name), you can use document_url rules with regex-like patterns to avoid listing every single URL. As shown in the image below, the browser will match the current URL pattern and speculate the next likely step.
<script type="speculationrules">
{
"prerender": [
{
"document_url": {
"and": [
{ "url_pattern": "/products/*" },
{ "url_pattern": "/checkout" }
]
}
}
]
}
</script>
Step 4: Verifying Implementation in DevTools
You don’t have to guess if it’s working. Open Chrome DevTools, go to the Application tab, and look for the Speculative loads section. Here you can see which URLs are being prerendered and whether they were successful or if they were evicted due to memory pressure.
Pro Tips for Production
- Watch your bandwidth: Prerendering a page is essentially a full page load. If you prerender 10 pages, you’re charging the user for 10 page loads. Stick to high-probability links.
- Avoid POST requests: Speculation rules only work for GET requests. Don’t try to prerender a checkout submission page.
- Combine with Font Optimization: Since prerendering loads the whole page, make sure you are optimizing font loading for LCP so the prerendered page doesn’t suffer from layout shifts upon activation.
- Check for ‘no-store’: If your server sends
Cache-Control: no-store, the browser will refuse to prerender the page.
Troubleshooting Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Page doesn’t feel instant | Only ‘prefetch’ was used instead of ‘prerender’ | Change rule type to prerender |
| High Server Load | Too many aggressive rules | Switch to ‘hover’ triggers or a smaller URL list |
| Rule ignored by browser | Invalid JSON syntax in script tag | Validate JSON; ensure type is exactly speculationrules |
What’s Next?
Once you’ve mastered the Speculation Rules API, the next step is refining your overall delivery pipeline. I recommend looking into advanced edge caching strategies to ensure that when the browser speculatively requests a page, the server responds in under 50ms. Pairing this with a comprehensive web vitals strategy will put your site in the top 1% of performance.