Prerendering is the rare performance change that can take Largest Contentful Paint close to zero without touching a single template. On Ray-Ban's product pages, mobile LCP went from 4.69s to 2.66s, a 43% improvement, with 29% of mobile and 50% of desktop navigations arriving prerendered. It is also the rare performance change that can corrupt your analytics, fire marketing tags before a person has navigated anywhere, and double the traffic hitting your origin. This is a staged rollout for whoever owns both the Core Web Vitals report and the conversion number on an e-commerce or travel site. Five stages, the eagerness setting and exclusion rule for each, what to measure before moving on, and the condition that should make you stop. At the end you can roll prerendering out one page type at a time and prove what it was worth.
What prerendering actually changes in your metrics
A prerendered page loads fully, hidden, before the click, and Chrome swaps it in when the user navigates. Three consequences matter before you write any rules.
- Core Web Vitals are measured from activation, not from the hidden load, so a prerendered page can report an LCP near zero. The
web-vitalslibrary from 3.1.0 follows the same rule and flags the navigation type. - The hidden page runs your JavaScript. Google Analytics, GPT and AdSense delay themselves until activation. Nothing else in your tag container does, unless you make it.
- The initiating page cannot see the outcome. Hit rate is measured on the speculated page, with
document.prerenderingandactivationStart.
If you cannot tell a prerendered view from an ordinary one in your own data, you are not ready for stage three.
Stage 1: prefetch the safe set, with exclusions written first
We start with prefetch, which pulls the document without executing it, so it cannot fire a tag or mutate state. Chrome's own guidance calls it relatively safe for most sites.
Write the exclusion list before the inclusion rule. Any URL that changes state on a GET request is a candidate for damage: /logout, add-to-basket links, one-click cancel links, anything with a token in the query string. Express these as an href_matches rule with a not clause. Where the server changes state anyway, live speculations can be cancelled with the Clear-Site-Data cache directives, available from Chrome 138.
Start at conservative or moderate eagerness, then confirm in the Application panel of DevTools that the rules are registered and the excluded paths are absent.
Stage 2: gate your tags before you prerender anything
This is the stage teams skip, and it is the one that produces phantom sessions and consent problems. In a prerendered page your container loads and your custom tags run while the user is still on the previous page.
Wrap every non-Google tag in a gate that resolves on the prerenderingchange event, or on first visibility if you also want to cover background tabs. Google tags delay themselves, but your consent gate still needs checking: verify that a block on non-essential tags holds during the hidden load rather than assuming it does. Both the Turkish and EU consent regimes care about when a tag fires, not about whether the user eventually clicked.
Then flag prerendered sessions in your own analytics with a custom dimension set from activationStart. Do not rely on PerformanceNavigationTiming.type, which has no prerender value.
Stage 3: prerender one page type at moderate eagerness
Pick the single highest-intent transition you have: listing to product page in retail, results to detail in travel. Apply a document rule scoped by selector to those links only, at moderate eagerness, which means hover for 200ms on desktop or viewport heuristics roughly 500ms after scrolling stops on mobile.
The concurrency limit shapes the design. Chrome allows two prerenders at eager, moderate or conservative, first in first out, against ten at immediate. You are not prerendering a listing page. You are prerendering the two most likely next steps.
Work out the cost first. Each speculation is a real page load, hit or miss. Count the extra requests, check what your CDN charges for them, and make sure you can turn the rules off at short notice during a campaign peak. Servers and CDNs can use the Sec-Purpose header to limit or refuse speculative requests.
Stage 4: measure on the destination, with a hit rate you trust
Log the classification server side, since client-side analytics will not see the hidden load. Three numbers decide whether stage five happens.
- Hit rate: prerendered activations divided by total views of that page type, split by device. Desktop and mobile behave differently enough that a blended number hides the result.
- Waste rate: prerenders started and never activated, against the extra origin or CDN load they cost.
- Field LCP for the page type, from CrUX or your own RUM, segmented by navigation type so the two populations stay separate.
Published hit rates give you a range to expect. Ray-Ban reported 29% on mobile and 50% on desktop for product pages. Monrif, across three news sites, reported 2.9% of mobile views and 13.9% of desktop views triggering prerendering at moderate. That gap is the difference between a selector aimed at high-intent tiles and a site-wide link rule. Plan on the mobile figure if your traffic is mostly mobile, as it is across Turkey and most of the region.
Stage 5: move to eager only where the hit rate earned it
If a page type is above roughly a quarter of desktop views arriving prerendered and the waste rate is affordable, tighten the trigger. eager fires after 10ms of hover on desktop. On mobile the behaviour changed recently: Chrome 143, stable on 2 December 2025, shipped mobile eager improvements, while Chrome's documentation describes the viewport trigger as firing roughly 50ms after the anchor enters the viewport and dates it from January 2026. The same change is dated differently in the two sources, so treat eager on mobile as version-dependent and verify it in DevTools on the Chrome build your traffic actually runs.
Keep eager to one or two page types. Site-wide eager is how a performance project becomes a capacity incident.
The rollout table
| Stage | Mechanism | Eagerness | Must be in place | Stop if |
|---|---|---|---|---|
| 1 | Prefetch, document rule | conservative or moderate | Exclusion rule for all state-changing GET URLs | Any excluded path appears in DevTools |
| 2 | Tag work only, no new rules | n/a | prerenderingchange gate on non-Google tags; prerender dimension | A tag fires while document.prerendering is true |
| 3 | Prerender, one page type | moderate | Server-side activationStart logging; rollback switch | Origin or CDN load passes the agreed budget |
| 4 | Measurement only | unchanged | Hit rate, waste rate and field LCP by device | Hit rate under 5% on both devices |
| 5 | Tighter trigger | eager, 1 to 2 page types | Stage 4 numbers for two weeks | Waste rate grows faster than hit rate |
Feature support
| Capability | Chrome and Edge | Firefox | Safari |
|---|---|---|---|
| Speculation rules prefetch and prerender | 109 | No prerender support | Behind a flag |
| eagerness, Speculation-Rules header | 121 | No | No |
| No-Vary-Search | 141 | 154 | No |
This is a Chromium optimisation with prefetch as the fallback elsewhere, which is how Ray-Ban handled browsers without prerender support.
Where this breaks down
Six limits worth stating before anyone promises a number:
- Chrome refuses to prerender in the conditions where speed matters most: Save-Data on, energy saver with a low battery, low-memory devices, the preload setting off, a background tab. On a mid-range Android fleet a real share of the audience is excluded by design, which is part of why mobile hit rates run low.
- Single-page applications only get their entry page prerendered. In-app route changes cannot be. If your product page is a client-side route, this buys you much less.
- Cross-origin needs a header. Same-site cross-origin prerender is cancelled unless the target sends
Supports-Loading-Mode: credentialed-prerender. Split checkout or booking subdomains are where stage three silently does nothing. - Stale state. A page prerendered three minutes ago shows a three-minute-old basket or seat map. Push updates into it, or exclude pages whose content moves under the user.
- Published conversion lifts are not forecasts. The Ray-Ban figures, +101% on mobile and +156% on desktop, are relative changes from one brand's own analytics workspace, on one page type, in prerender-capable browsers only.
- Delaying scripts to activation cuts both ways. It avoids wasted work, but gives back part of the LCP and CLS benefit, and running everything at activation can hurt INP.
[INTERNAL DATA NEEDED: Switas client hit rates and field LCP deltas by page type and device, from the web performance engagements, to replace the published third-party figures above with first-party ranges.]
Frequently asked questions
Will my LCP suddenly look impossibly good?
For the prerendered share, yes. Chrome measures from activation, so an activated prerender can report an LCP close to zero. That is a real user experience, but segment your reporting by navigation type so you can still see how the non-prerendered majority is doing.
How do I know a page was prerendered?
After activation, read performance.getEntriesByType('navigation')[0].activationStart. A non-zero value means the page was prerendered. During the hidden phase, document.prerendering is true.
Do I need to change Google Analytics?
Google Analytics, GPT and AdSense already delay until activation. Your own custom tags, and most third-party marketing pixels, do not. Those are the ones to gate.
How many pages can Chrome prerender at once?
Two at eager, moderate or conservative, on a first in first out basis, so a new speculation cancels the oldest. Ten at immediate, which is the default for list rules.
Should we use immediate eagerness on mobile since there is no hover?
Only on a tightly scoped selector, such as the first few tiles on a listing page, which is what Ray-Ban did. immediate applied broadly turns every page into ten speculative loads.
Where do query parameters fit in?
No-Vary-Search lets a prerendered page be reused across URLs that differ only in parameters you declare irrelevant, which matters for filtered listing pages. It needs the response header; the expects_no_vary_search hint alone does not enable reuse.
One next step
Run stages 1 and 2 this sprint: write the exclusion rule, gate the non-Google tags, ship the prerender dimension into your analytics. If you would rather have hit rate, waste rate and field LCP measured properly before anyone argues about eagerness, our web performance services team runs this rollout as a measured engagement.
Sources
- Prerender pages in Chrome, Chrome for Developers
- Implementing speculation rules on complex sites, Chrome for Developers
- Debug speculation rules with DevTools, Chrome for Developers
- Improvements to the Speculation Rules API, Chrome for Developers
- Chrome 143 release notes, stable 2 December 2025
- Ray-Ban prerendering case study, web.dev, 28 January 2025
- Monrif Core Web Vitals case study, web.dev, 9 December 2025
- prerenderingchange event, MDN
- Unblock Google tags when using consent mode, Tag Manager Help







