What really happens during a prerender
Speculation Rules are a JSON ruleset that a page ships either inside a script element of type speculationrules or through the Speculation-Rules HTTP header. Two levels exist. prefetch retrieves only the target document. prerender goes considerably further: supporting browsers fetch the content, render it and store it in an invisible tab held in the document's in-memory cache - including all subresources, execution of all JavaScript and even the data fetches started by that JavaScript (MDN Web Docs, Speculation Rules API). For the visitor, the click then feels as if the page had been ready all along.
On click the browser swaps the invisible tab for the current page. That moment is called activation - and this is exactly where engineering and measurement part ways. Several seconds can pass between the start of the prerender and activation, during which the page is already fully running without anyone seeing it. Three building blocks expose that state in code: the document.prerendering property, the prerenderingchange event that fires on activation, and activationStart from the PerformanceNavigationTiming entry, which reports the time between prerender start and activation (MDN Web Docs, Speculation Rules API).
- Deferred interfaces - Notifications, Geolocation, camera and microphone access, Web Audio, sensors and
ServiceWorkerRegistration.register()return a pending promise inside the pre-tab and only continue after activation (MDN Web Docs). - Blocked interactions - fullscreen,
Window.open(), payment dialogs and clipboard access fail because they require user activation, focus or visibility (MDN Web Docs). - Silent dialogs -
alert(),confirm()andprompt()return without displaying anything (MDN Web Docs). - Delayed side effects - downloads only start after activation, cross-origin iframes load only then, and
sessionStorageworks on a clone that is swapped back on activation (MDN Web Docs). - Cancellation triggers - a navigation to a different site discards the prerender immediately, as do
javascript:,data:,blob:andabout:URLs (MDN Web Docs).
What the browser does not hold back is ordinary analytics JavaScript. A counting pixel that fires on load sends its hit from the invisible tab as well. For reporting this means the page counts as viewed even though the visitor may have scrolled past and never clicked the link. That gap is not a browser bug but a deliberate design decision - the platform provides document.prerendering and prerenderingchange precisely so a script can control its own behaviour.
Prefetch and prerender requests carry the Sec-Purpose request header with the value prefetch or prefetch;prerender respectively (MDN Web Docs, Speculation Rules API). That allows speculative hits to be separated from real ones directly in the web server log - an analysis that works without touching the front end and that makes the later hit rate calculable in the first place.
To put the amount of potential resource wastage in perspective: a prerender uses about the same amount of resources as rendering an iframe.
— MDN Web Docs, Speculation Rules API
Why the effect has gone mainstream since Chrome 121
Prerendering through Speculation Rules is not new: Chrome and Edge have supported the rules since version 109 (Chrome for Developers). The technique only became practical with the additions of the following releases. Chrome 121 introduced the eagerness parameter and made the source key optional; from Chrome 122 the full package of document rules and graded eagerness was available (Chrome for Developers). Chrome 136 added the tag field for telling rulesets apart, Chrome 138 the target_hint for targets in new tabs (Chrome for Developers). Only document rules allow the short formulation: take every link in this document, except these.
| Chrome version | What was added | What it means for measurement |
|---|---|---|
| 109 | Prefetch and prerender via Speculation Rules | First navigations without a visible load - and first hits without a viewer |
| 121 | eagerness parameter, source optional | Rules become adjustable, the hit rate becomes steerable |
| 122 | Document rules fully available | One rule block covers all links, exclusions become mandatory work |
| 136 | tag field for rulesets | Rulesets can be told apart in developer tools |
| 138 | target_hint | Targets in new tabs arrive prerendered too |
Adoption is now substantial. In the Web Almanac 2025 measurements, 3 percent of desktop and 5 percent of mobile pages among the top 1,000 websites ship Speculation Rules; across the long tail of the top 10 million it is 24 percent on desktop and 35 percent on mobile (HTTP Archive Web Almanac 2025). The jump is largely explained by content management: since version 6.8, WordPress ships speculative loading on the front end by default, configured as prefetch with the conservative eagerness level, excluding logged-in users and installations without pretty permalinks (WordPress Core, Speculative Loading in 6.8).
Raising that default from prefetch to prerender - through a filter in the CMS or a single line in your own ruleset - changes the data picture instantly. And prerendered hits arise even without a ruleset of your own: Chrome prerenders pages from the address bar when its prediction based on browsing history is highly confident, likewise when pointing at an entry in the bookmarks bar and on search result pages when the search engine instructs it (Chrome for Developers). At the same time prerender remains a hint rather than an instruction: the browser may pass on it because of user settings, memory pressure or its own heuristics (Chrome for Developers).
A measurement model that treats every page view alike was defensible a few years ago. With 35 percent of mobile pages in the broad web capable of speculation (HTTP Archive Web Almanac 2025) and prerendering triggered straight from the browser address bar (Chrome for Developers), separating by navigation type has become a basic requirement for numbers you can rely on.
How prerendering distorts measurement
The distortion shows up in four typical patterns. They hit different metrics but share one cause: an event is recorded at the moment of preparation instead of the moment of viewing. Knowing the patterns makes them far easier to spot in your own data - much like automated traffic, which waters down the same reports when left unfiltered and which we cover in the article on filtering bot traffic out of analytics.
Every prepared but unactivated tab produces a hit. Reach looks larger although no human saw the page. The pages listed in the ruleset are affected most, so the error is not spread evenly.
A hit without a viewer produces no scrolls, no clicks and no active time. In reporting it appears as an instant bounce with zero seconds of session duration and pulls both metrics in the wrong direction.
If a goal event fires on load of a confirmation page, it can already trigger inside the pre-tab. When the page is genuinely opened later, a second signal appears - and neither count is correct.
Without correction the clock starts at the prerender. LCP then drops close to zero because rendering happened long before viewing. The result is an average that hides the real experience of slow first visits.
A worked example makes the magnitude tangible: if a counter reports 1,000 page views on a given day and 220 of them were produced in a pre-tab that was not activated, only 780 views were actually seen - 22 percent of the reported figure was pure preparation (illustrative figures). How high the share really is depends entirely on the ruleset, the eagerness level and user behaviour. Only the direction is dependable: without correction the counter reports more than anyone has seen.
A prerender is a real request to your server. If the ruleset contains a URL that changes something - ?add-to-cart=, a logout link, a confirmation link, a mark-as-read endpoint or a URL carrying a click parameter - that action is triggered without anyone asking for it. Such paths belong in the exclusions. For stored prefetches that have become invalid, the prefetchCache value of the Clear-Site-Data response header is available, for instance on logout (MDN Web Docs, Speculation Rules API).
Defer trackers until activation
The clean answer is not to avoid prerendering but to tie measurement to activation. The pattern is short: if the document is in the prerendering state, measurement is attached to the prerenderingchange event and started there exactly once; if it is running normally, it starts immediately. Scripts unaware of that state otherwise count inside the pre-tab (MDN Web Docs, Speculation Rules API).
function startMeasurement() {
// page view, session start, goal events
}
if (document.prerendering) {
document.addEventListener('prerenderingchange', startMeasurement, { once: true });
} else {
startMeasurement();
}For reporting it also matters whether a page was prerendered at all. activationStart provides that information: a value greater than zero means time passed between prerender start and activation. Combined with document.prerendering this yields a dependable detection that also works when the script only runs after activation (MDN Web Docs, Speculation Rules API).
const nav = performance.getEntriesByType('navigation')[0];
const activation = nav ? nav.activationStart : 0;
const wasPrerendered = document.prerendering || activation > 0;
const navigationType = wasPrerendered
? 'prerender'
: (nav ? nav.type : 'navigate'); // navigate | reload | back_forward- Page view - send it after activation, not on document load.
- Session start - tie it to the same condition, otherwise the session begins in the invisible tab and time on site starts too early.
- Goal events - fire order, form and lead signals only after activation so no duplicate count appears.
- Events inside the pre-tab - if you need them, buffer them and replay them after activation with the correct timestamp.
- Server side - keep requests carrying the
Sec-Purposeheader separate in log analysis instead of counting them as reach. - Check after every deploy - a changed script version can silently remove the deferral; a recurring browser check with real page rendering surfaces that.
Chrome DevTools shows under Application and Speculative loads which rules matched, which speculation was started and why it may have been discarded. A test run on a preview environment with the ruleset enabled reveals within minutes whether your counter fires in the pre-tab or waits for activation.
Relate Web Vitals to activation
Prerendering genuinely improves perceived speed. The Chrome documentation describes the effect as near zero LCP, reduced CLS - because load-time layout shifts happen before the first view - and improved INP (Chrome for Developers). That is precisely why measurement needs a defined zero point. Without correction, time is measured from the prerender start and the metric no longer describes how long someone waited but how long the browser worked ahead.
const nav = performance.getEntriesByType('navigation')[0];
const activation = nav ? nav.activationStart : 0;
// Evaluate the LCP entry relative to activation
const lcpAfterActivation = Math.max(0, lcpEntry.startTime - activation);
// The same principle applies to FCP, TTFB and your own marks
const ttfbAfterActivation = Math.max(0, nav.responseStart - activation);The second step matters more than the formula: separate instead of averaging. The Chrome UX Report has exposed navigation types since the 202403 dataset, released on 9 April 2024 (Chrome UX Report, release notes). How strongly a navigation type moves aggregates is shown by the back/forward cache precedent: with the broad rollout in Chrome 97, the pass rate for CLS improved by 4.4 percent and for LCP by 2.4 percent (Chrome UX Report, release notes, dataset 202201). A growing prerender share shifts averages the same way - upward, without the page itself getting any better.
| Navigation type | What it says about the page | Pitfall in reporting |
|---|---|---|
| navigate | Regular first load without preparation | Gets masked in the average by fast special types |
| prerender | Fully prepared, load time before activation | LCP close to zero pulls the overall value upward |
| back_forward | History navigation without cache restore | Frequently conflated with the cached case |
| back_forward_cache | Restore from the back/forward cache | Very fast values that say nothing about first loads |
| reload | Reload, often after a problem | A cluster points to errors rather than interest |
In practice a performance report needs at least one line for regular first loads kept separate from all accelerated types. How field and lab measurement complement each other is covered in the article on field data versus lab data for Core Web Vitals; where the load time of a first visit is actually spent is shown by the breakdown in LCP subparts from TTFB to render delay. For applications with client-side routing there is the added question of how view changes are captured at all - see the article on Core Web Vitals in single-page apps.
Evaluate hit rate and impact per navigation type
Once counting is activation-based, prerendering turns from a source of error into a metric. What matters is not only how many navigations arrived prerendered, but also how many speculations came to nothing. Together the two sides give the hit rate - and with it the answer to whether the ruleset is well tuned or burning bandwidth.
- Prerender share - the proportion of activated prerenders among all measured navigations. If it rises, the site feels faster to returning visitors.
- Hit rate - activated prerenders divided by the number of speculative requests in the server log (
Sec-Purpose). A low rate means plenty of preparation and little benefit. - LCP delta per type - median LCP of regular first loads against the activation-corrected median of prerendered loads. That is the honest gain.
- INP per type - evaluate interaction latency separately, because a prerendered document is already initialised on the first click.
- Waste ratio - bytes transferred for speculations that were never activated, broken down by device class.
- Entry pages - the distribution of activated prerenders across page types; if everything piles up on a few URLs, the ruleset is either too narrow or too broad.
The analysis pays off above all over time. A ruleset that achieves a good rate at launch can look considerably worse after a navigation relaunch because different links now sit in the viewport. A recurring report that lists navigation types separately surfaces such shifts without anyone reading raw data daily - scheduled reports and status pages summarise the state automatically.
Reported page views tell you how often the browser worked. Activated page views tell you how often a human saw the page. As long as both numbers sit side by side, every deviation can be explained. As soon as only one of them is reported, guesswork begins.
Spotting miscounts: signals in the raw data
Not every website can change its measurement script right away. Until then a diagnosis based on existing data helps. Prerendering leaves characteristic traces, because a hit without a viewer inevitably lacks any follow-up interaction. The signals below rarely appear alone - when two or three coincide, the suspicion is well founded.
- Page views with zero seconds of active time - no scroll, no click, no visibility change, clustered on the same URLs (project experience).
- A bounce rate that jumps without cause - the rate rises on the day a ruleset or a CMS update was rolled out (project experience).
- Duplicated goal signals - the same order or form confirmation appears twice within a short interval.
- Mismatch between log and counter - the web server reports considerably more requests with
Sec-Purposethan the counter shows prerendered views. - Entries on deep pages without referrer - target pages from the ruleset show up as entry pages although they are barely linked in the menu.
- An LCP distribution with two peaks - one peak close to zero, a second in the realistic range; a strong hint at uncorrected activation times.
Zero-second views also arise from automated traffic, from failed scripts or from dropped mobile connections. Prerendering is one possible explanation among several. The diagnosis only becomes reliable once the speculative requests from the server log are added - only then can a share be quantified instead of assumed.
A practical intermediate step: for two weeks, attach an additional property to the page view carrying the detected navigation type, without changing the existing count. That creates a baseline for comparison before you make the actual switch. The effort is a few lines of code, and the insight is far greater than any estimate.
Resource cost: do not set eager rules without limits
Every speculation costs twice: bandwidth at the visitor and compute time on your server. The Chrome documentation is explicit - prerendering does use additional memory and network bandwidth, and you should be careful not to over-prerender (Chrome for Developers). The web.dev learning material recommends using prerendering sparingly and only where navigation to the target is fairly likely; prefetching should stay on fast connections and be skipped when the Save-Data signal is set (web.dev, Learn Performance).
| Eagerness | Trigger | Limit prefetch / prerender |
|---|---|---|
| immediate | As soon as the rules are parsed | 50 / 10 |
| eager | From roughly 10 ms of hover on desktop, viewport heuristics on mobile | 50 / 10 |
| moderate | 200 ms of hover or pointerdown, whichever comes first | 2 / 2 (oldest is dropped) |
| conservative | Only on pointerdown or touchstart | 2 / 2 (oldest is dropped) |
The limits come from the Chrome documentation; once a limit is reached, the browser cancels the oldest speculation in favour of the new one (Chrome for Developers). That caps the damage but does not remove it: ten parallel prerenders correspond in order of magnitude to ten additionally rendered iframes (MDN Web Docs, Speculation Rules API). On mobile devices with limited data allowances and on servers with expensive, personalised pages that is a noticeable item.
Speculative requests pass through the same application layer as real ones: database queries, search indexes, cart sessions and rate limits. An immediate rule on an overview page with 60 links can multiply the number of requests to expensive endpoints. Set the level deliberately, watch response times afterwards and have outliers reported through alerting and notifications instead of discovering them in the monthly report.
Setting up the ruleset cleanly: exclusions and edge cases
A good ruleset is short and consists mostly of exceptions. Document rules let you include all links and exclude individual patterns - via href_matches for paths and selector_matches for CSS selectors. This marks areas that should not be loaded speculatively at all without maintaining every URL by hand (MDN Web Docs, Speculation Rules API).
{
"prerender": [
{
"eagerness": "moderate",
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout*" } },
{ "not": { "href_matches": "/*\\?*(^|&)add-to-cart=*" } },
{ "not": { "href_matches": "/account/*" } },
{ "not": { "selector_matches": ".no-prerender" } },
{ "not": { "selector_matches": "[rel~=nofollow]" } }
]
}
}
]
}- Exclude state-changing paths - logout, cart, order confirmation, approval and delete actions.
- Leave out personalised areas - account, customer portal and anything rendered per user that triggers expensive queries.
- Mark links in the markup - a class such as
.no-prerenderon critical links saves later path lists and survives relaunches better. - Mind the Content Security Policy - if the page ships a
script-srcdirective, the'inline-speculation-rules'source, a hash or a nonce has to be added, otherwise the ruleset is discarded (MDN Web Docs). - Cross-origin cases - prerendering is restricted to the same origin by default; cross-origin same-site requires the target to send
Supports-Loading-Mode: credentialed-prerender(MDN Web Docs). - Feature detection -
HTMLScriptElement.supports('speculationrules')checks support before rules are inserted dynamically (MDN Web Docs).
MDN classifies Speculation Rules as a feature with limited availability that is not part of Baseline, because it is missing in widely used browsers: Chrome and Edge support it from version 109, Firefox does not, and Safari keeps it behind a flag (MDN Web Docs, Speculation Rules API). For measurement this means part of your traffic is affected and part is not - which is a further argument for reporting navigation types separately.
Measure what was seen, not what the browser prepared
All the corrections described lead to the same point: a page view counts from activation, not from rendering. That is how the cookieless first-party analytics from XICTRAQ works - the counter starts when the document becomes active, and the detected navigation type travels with the hit instead of disappearing into an average. Web Vitals are collected in the field and related to the activation moment so a prepared load does not artificially flatter the distribution.
The page view is recorded on activation. Prepared but unactivated documents do not appear as reach and distort neither bounce rate nor time on site.
First load, prerender, history navigation and cache restore are distinguished. Metrics can be read per type instead of blurring into one average.
LCP, INP and CLS come from real sessions rather than a lab run, related to the activation moment and broken down by device class.
Operating this stays manageable. A tracking script served from your own domain, a ruleset with clear exclusions and a report that lists navigation types separately - that is all it takes for numbers you can defend. Anyone already documenting evidence, for instance for the NIS2 registration with the BSI and management duties, knows the principle: a traceable measurement costs less effort than a retrospective reconstruction. The same deploy discipline applies to mandatory front-end elements such as labelling AI chatbots under the AI Act - whatever a deploy can silently remove belongs on a regular check.
Prerendering is not going away, quite the opposite: fast navigations are a visible quality advantage, and content management systems now ship the rules by default (HTTP Archive Web Almanac 2025). The question is therefore not whether prerendering affects you but whether your numbers reflect the technology. A look at the live demo shows what activation-based reporting looks like day to day; the plan overview summarises which analyses are included at which scope. And if you need evidence for your own data situation, the cookieless analytics feature reports counted and activated views side by side.
This article is based on data and documentation from: Chrome for Developers - Prerender pages in Chrome for instant page navigations (Chrome versions 109, 121, 122, 136 and 138, eagerness levels and triggers, limits of 50 prefetch / 10 prerender for immediate and eager and 2 / 2 for moderate and conservative, prerendering from the address bar, bookmarks bar and search results, the hint character of speculation, effects on LCP, CLS and INP, warning against over-prerendering); MDN Web Docs - Speculation Rules API (rendering in an invisible tab including subresources and JavaScript, document.prerendering, prerenderingchange, PerformanceNavigationTiming.activationStart, the Sec-Purpose header, deferred and restricted interfaces, cancellation triggers, Clear-Site-Data with prefetchCache, inline-speculation-rules in the CSP, Supports-Loading-Mode credentialed-prerender, the resource comparison with an iframe, browser support and Baseline status); web.dev - Learn Performance, Prefetching, prerendering and service worker precaching (sparing use, Save-Data signal); Chrome UX Report (CrUX) - release notes (navigation types in dataset 202403, released 9 April 2024; back/forward cache rollout in Chrome 97 with 4.4 percent better CLS and 2.4 percent better LCP pass rates, dataset 202201); HTTP Archive Web Almanac 2025 (Speculation Rules adoption of 3 percent desktop and 5 percent mobile in the top 1,000, 24 percent desktop and 35 percent mobile in the top 10 million; Core Web Vitals pass rates of 48 percent mobile and 56 percent desktop); WordPress Core - Speculative Loading in 6.8 (default of prefetch with conservative, exceptions for logged-in users and missing pretty permalinks). The worked examples using 1,000, 780 and 220 views are illustrative and are not measurements.
Frequently asked questions about prerendering and measurement
Does prerendering count my page views twice?
document.prerendering and prerenderingchange removes both issues (MDN Web Docs, Speculation Rules API).Do I have to disable Speculation Rules to measure cleanly?
conservative level, which speculates only on pointerdown or touchstart and keeps at most two speculations in parallel (Chrome for Developers).How do I recognise a prerender in the server log?
Sec-Purpose request header with the value prefetch or prefetch;prerender (MDN Web Docs, Speculation Rules API). If that header is written to the access log, speculative hits can be separated from regular ones without touching the front end. The ratio of those requests to the views activated later gives the hit rate of the ruleset.Does prerendering distort my Core Web Vitals?
activationStart and navigation types are reported separately, the real gain stays visible without flattering first loads. The Chrome UX Report has exposed navigation types since dataset 202403 (Chrome UX Report, release notes).