Speeding Up Navigation With Resource Prefetching
Prefetching is a performance technique that lets you fetch resources a user is likely to need before they actually navigate to them. By starting the download during idle time, you can make subsequent page loads feel near-instant. This article walks through implementing prefetching in two ways: with <link rel="prefetch"> tags and with HTTP Link headers, using a sample e-commerce site with a promotional landing page linking to a single product page.
Establishing a Baseline
To measure the impact of prefetching, you first need a baseline. Using the sample app with DevTools open:
- Open the Network tab.
- Set the Throttling drop-down to Fast 3G to simulate a slower connection.
- Click Buy now to navigate to the product page.
Under these conditions, the product-details.html document takes approximately 600 ms to load.
Prefetching With a <link> Tag
Given the high likelihood that a visitor will click through to the product details, that page is an ideal candidate for prefetching. Add the following element to the <head> of views/index.html:
<link rel="prefetch" href="/product-details.html" as="document">
The as attribute is optional but recommended. It assists the browser in setting appropriate request headers and determining whether the resource is already cached. Common values include document, script, style, font, and image.
To verify the prefetch is working, open DevTools, clear the Disable cache checkbox, and reload the app. The Network panel will show product-details.html being fetched at the lowest priority alongside the landing page.
The fetched document is held in the HTTP cache for five minutes. After that window, the normal Cache-Control rules apply, which in this case (public, max-age=0) means the cached copy is no longer used.
Measuring the Improvement
Reload the app and click Buy now again. The Network panel will reveal two key changes compared with the baseline:
- The Size column shows "prefetch cache," indicating the resource came from the browser's cache rather than the network.
- The Time column drops to roughly 10 ms—an approximate 98% reduction from the original 600 ms load time.
Progressive Enhancement With the Network Information API
Prefetching consumes bandwidth, so it's best deployed selectively. For users on slow or metered connections, you can avoid unnecessary data usage by making prefetching conditional on network quality using the Network Information API.
First, remove the <link rel="prefetch"> tag from views/index.html. Then, in public/script.js, declare a function that dynamically injects the prefetch tag only when appropriate:
function injectLinkPrefetchIn4g() {
if (navigator.connection.effectiveType.includes('4g')) {
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = '/product-details.html';
link.as = 'document';
document.head.appendChild(link);
}
}
This function checks the effectiveType property of the Network Information API. If the user is on a 4G (or faster) connection, it creates a <link> element with the appropriate attributes and injects it into the page's <head>.
Next, add a reference to script.js in views/index.html just before the closing </body> tag. Loading the script at the end of the page ensures it executes only after the page has been fully parsed.
To prevent prefetching from competing with critical rendering resources, trigger the injection on the window.load event:
<script>
window.addEventListener('load', injectLinkPrefetchIn4g);
</script>
With this setup, the landing page prefetches product-details.html only on fast connections. Under the Online throttle in DevTools, the product page will appear in the Network panel. When the throttle is set to Slow 3G, only the landing page's own resources are loaded—product-details.html is absent.
Prefetching CSS via the HTTP Link Header
The HTTP Link header achieves the same effect as the <link> tag and can be used interchangeably, with no meaningful performance difference between the two approaches. It can also target any prefetchable resource type.
To further improve the product page's rendering, you can prefetch its main stylesheet by adding a Link header to the server response for the landing page. In server.js, locate the get() handler for the root URL (/) and add the following line at the beginning of the handler:
res.set('Link', '</style-product.css>; rel=prefetch; as=style');
After restarting the server and reloading the app, the Network panel will show style-product.css being downloaded at low priority alongside the landing page. When you then click Buy now, the stylesheet is retrieved from the prefetch cache, loading in just 12 ms rather than from the network.



