Viewport Prefetching with Quicklink
This guide is part of Speculative Loading & Prefetching, within Network & Server Response Optimization. Viewport prefetching assumes that links a user can see are more likely to be clicked than links they cannot. Quicklink, a small library from the Chrome team, implements this: it watches links with IntersectionObserver, waits until the browser is idle (requestIdleCallback), checks that the connection is not slow or in data-saver mode, and prefetches the visible links' documents with <link rel="prefetch"> or fetch(). When the user clicks, the HTML is already in the cache.
It works in all modern browsers, unlike speculation rules, and requires little configuration. The risk is wasted bandwidth and server load on link-dense pages, which configuration options (origins, ignores, throttling, limits) control. In Chromium, Quicklink can also emit speculation rules for prerendering.
Rapid Diagnosis
- Check link density: pages with hundreds of visible links (mega menus, footers) cause many prefetches.
- Check server logs for prefetch request volume (look for
Sec-Purpose: prefetchor thePurposeheader). - Check cache headers on HTML: prefetched documents must be cacheable for a short time to be reused.
- Check browser support of
rel=prefetch(Safari support has been limited; Quicklink falls back tofetch).
Root Cause Analysis
1. Too many visible links. Menus and footers trigger dozens of prefetches.
2. Uncacheable HTML. no-store responses cannot be reused from the prefetch cache.
3. Third-party links. Prefetching external sites wastes bandwidth and leaks intent.
4. Expensive server pages. Prefetches multiply load for uncached pages.
Step-by-Step Resolution
1. Install and configure with limits
import { listen } from 'quicklink';
window.addEventListener('load', () => {
listen({
origins: [location.hostname], // same-site only
ignores: [/\/logout/, /\/cart/, (uri, el) => el.hasAttribute('download') || el.closest('nav.mega-menu')],
throttle: 2, // max concurrent prefetches
limit: 12, // total prefetches per page
timeout: 2000, // requestIdleCallback timeout
});
});
// trade-off: a low limit protects bandwidth and servers but may skip links the
// user actually clicks; tune with analytics on which prefetches were used.
2. Make prefetched HTML reusable
Prefetched documents are kept for a short time (typically up to 5 minutes) regardless of cache headers in some browsers, but Cache-Control: no-store can prevent reuse. Use short max-age or private caching for HTML that should be prefetchable.
3. Exclude navigation chrome
Ignore links in mega menus, footers and long lists of tags, which are visible but rarely clicked compared with content links.
4. Combine with speculation rules in Chromium
Use Quicklink for broad, cross-browser prefetch, and speculation rules for prerendering high-probability links in Chromium. Quicklink's prerender option generates speculation rules for this purpose.
Verification
In the Network panel, filter by "prefetch" type or look for low-priority document requests after load. Click a prefetched link and check that the document came from the prefetch cache (size column shows "prefetch cache" or similar). In analytics, compare LCP and TTFB for navigations to prefetched links. Watch server request volume for prefetch-tagged requests.
Worked Example: A Regional News Homepage
A news site added Quicklink with default settings. The homepage displayed about 60 headline links; prefetches averaged 48 per page view, and origin requests for article HTML tripled during peak traffic, although articles were cached at the CDN. Only 7% of prefetches were used. The team restricted Quicklink to links in the main content area (ignoring navigation, footer and "most read" lists), set a limit of 12 and throttle of 2, and prioritised the top stories by marking them data-prefetch-priority. Prefetches per page view fell to 12 with a 22% usage rate, and TTFB for subsequent article navigations dropped from 380ms to under 20ms for prefetched articles. CDN request volume settled at 30% above baseline.
Viewport Prefetch vs Hover Prefetch
Viewport prefetching starts early — as soon as links are visible and the browser is idle — giving maximum lead time, but with low per-link probability. Hover or pointer-down prefetching (speculation rules at moderate or conservative eagerness, or libraries like instant.page) starts later but with much higher probability. On pages with few, prominent links (a "next article" button, the top search result), viewport prefetching works well. On link-dense pages, hover-based approaches waste much less. Many sites use both: viewport prefetch for a small set of prioritised links, hover prefetch for the rest.
Prioritising Which Links to Prefetch
Not all visible links are equal. Content links in the main column (the next article, related stories, the first few search results) are clicked far more often than navigation, footer or tag links. Restrict Quicklink to the main content area with the el option, or mark high-value links with a data attribute and prefetch only those. For listing pages, prefetching only the first few results above the fold often captures most of the benefit. Analytics on which prefetched URLs were later navigated to show which areas earn their prefetches, and which only add load. Revisit the configuration after redesigns.
Common Mistakes
- Prefetching every visible link. Wastes bandwidth and server capacity.
- Prefetching third-party links. Leaks browsing intent and wastes bandwidth.
- Uncacheable HTML. Prefetched documents cannot be reused.
- Starting before load. Prefetches compete with the current page's critical resources.
Edge Cases
SPAs. Quicklink can prefetch route chunks instead of documents with custom logic; frameworks often provide this built in.
Authentication. Prefetched pages use current cookies; if auth state changes, the prefetched document may be stale.
Analytics. Prefetch does not execute scripts, so analytics are unaffected (unlike prerender).
Slow connections. Quicklink skips prefetching on slow effective connection types and with Save-Data.
FAQ
What does Quicklink do?
It prefetches links that are visible in the viewport when the browser is idle, on fast enough connections, to make subsequent navigations faster.
Does Quicklink work in Safari and Firefox?
Yes. It uses rel=prefetch where supported and falls back to fetch() with low priority elsewhere.
Can Quicklink prerender pages?
In Chromium, Quicklink can generate speculation rules for prerendering. Use it for a small number of high-probability links.
Will it overload my server?
It can on link-dense pages without limits. Use origins, ignores, limit and throttle, and cache HTML at the CDN.
Does prefetching respect data saver?
Quicklink checks navigator.connection.saveData and slow connection types, and skips prefetching when they apply.
How is this different from instant.page?
instant.page prefetches on hover or touch start, with higher hit rates and less lead time. Quicklink prefetches on visibility.
Does prefetching affect SEO?
No. It only affects users' browsers; crawlers do not run it in a way that changes indexing.
How long are prefetched documents kept?
Typically a few minutes in the browser's prefetch cache. If the user clicks after that, the document is fetched again.
Should Quicklink run on every page?
Run it where subsequent navigations are common and predictable, such as listing and article pages. Skip it on checkout flows and pages with very many links.
Can Quicklink prefetch on hover instead?
Quicklink focuses on viewport visibility. For hover-based prefetching, use speculation rules with moderate eagerness or a library such as instant.page.
Does Quicklink work with client-side routers?
It prefetches documents by default. For single-page apps, use the router's own prefetching or customise Quicklink to load route chunks instead.
Related
- Prerender vs prefetch cost trade-offs — choosing speculation actions.
- Speculation rules for instant navigations — Chromium prerendering.
- Native lazy loading vs IntersectionObserver — the same visibility primitive.