Cloaking census · pilot + open protocol
How many sites cheat PageSpeed?
A PageSpeed score is money — so it gets gamed. The sharpest cheat is cloaking: detect Lighthouse or PageSpeed Insights and serve it a stripped, fast page while real visitors keep getting the heavy one. The techniques are publicly documented. What nobody has published is a number: what share of sites actually do it. We did two honest things instead of guessing — ran a real user-agent-flip pilot across the top 2,000 sites, and published the full preregistered protocol to measure it at web scale.
The honest headline: not a number yet — but a floor and a method
Search “how many sites cheat PageSpeed” and you get anecdotes, vendor threads, and one or two GitHub repositories — no population estimate with a denominator, a sampling frame, or a confidence interval. That gap is real, and the wrong way to fill it is to crawl a handful of sites and announce a percentage. So this study is deliberately two-part: a pilot that puts a defensible lower bound on the crudest, most-detectable form of cloaking, and a registered census protocol precise enough to produce the real number without overclaiming.
The pilot tests only one thing — whether a site hands a different raw HTML page to a Lighthouse-branded user-agent than to a normal one, from the same IP. That is the bluntest cloaking instrument there is, and it is a strict floor: it cannot see client-side JavaScript cloaking, IP/reverse-DNS cloaking, or User-Agent Client Hints branching, and it does not run the page. A small floor is still informative — it tells you where the cheating isn't (in the easy-to-catch server layer of the most-visited sites) and therefore where a real census has to look. You can run the same core probe on any single URL with our free PageSpeed cloaking test.
What “cheating PageSpeed” actually means
PageSpeed Insights reports two different things about a URL. Field data comes from the Chrome UX Report (CrUX): real Chrome users, their real LCP, INP and CLS over a trailing 28 days. Lab data is a single Lighthouse run in a simulated, throttled environment. The two can legitimately diverge — but only the lab run is a controllable, on-demand, advertisable deliverable. That is the incentive: lab scores are easy to sell, and real-user performance is hard to move because it needs less payload, less main-thread work, and fewer round trips.
Lighthouse's performance score is not a measure of page size; it is a weighted blend of metrics. The weights make it obvious which manipulations pay off — suppress JavaScript and you move the heaviest lever, Total Blocking Time:
| Metric | Weight | What a cloaker targets it with |
|---|---|---|
| Total Blocking Time | 30% | Block or defer JavaScript only for the measuring client |
| Largest Contentful Paint | 25% | Early oversized/hidden LCP candidate; suppress the real hero |
| Cumulative Layout Shift | 25% | Test-only layout stability; hold back late-shifting content |
| Speed Index | 10% | Simplified above-the-fold for the lab profile |
| First Contentful Paint | 10% | Skeleton/partial DOM, early document.close() |
This is a lab-tool split-view problem, not a claim about Google Search ranking. Google's spam policy defines cloaking as showing search engines different content to manipulate rankings; PageSpeed cloaking is analogous but distinct — it targets a performance measurement, and it must be defined and measured on its own terms. Throughout, the object is synthetic Lighthouse/PSI split-view serving, not search fraud.
The technique taxonomy — and what a single fetch can and can't see
The public record already documents the mechanisms. The motivating source is a February 2024
GoogleChrome/lighthouse issue opened by a Shopify performance architect, reporting third-party scripts
that detect Lighthouse — by the Chrome-Lighthouse user-agent marker, a
navigator.platform of Linux x86_64, or a moto g power
device string — and then run “LCP hacks,” block JavaScript, prevent lazy images and iframes from
loading, and stop HTML parsing with document.close(). The taxonomy below classifies those
and the variants a census must anticipate. The last column is the honest scope statement for our pilot.
| Family | Examples | Seen by a raw UA-flip fetch? |
|---|---|---|
| Fingerprint detectors | Lighthouse UA marker, navigator.platform, UA-Client-Hints, headless/automation, canvas/font, egress IP & reverse DNS | Partly — only the UA-string check; not UA-CH, IP or JS fingerprints |
| Payload suppression | Block first-/third-party JS, analytics, chat, ads; suppress images/fonts/iframes; skeleton DOM | Only if done server-side; client-side blocking is invisible to a fetch |
| Metric manipulation | Early oversized/transparent LCP candidate; test-only CLS/TBT tricks | No — needs a real render & trace |
| Server / middleware | Edge worker or CDN branch on UA/UA-CH/IP; separate templates; redirect divergence | UA-branched HTML: yes. IP/UA-CH branches: no |
| Benign split views | Responsive design, geo/locale, consent banners, A/B tests, bot protection, cache state | Must be excluded — these are not cloaking; the pilot's controls do this |
Two prior efforts bracket the problem. The closest PageSpeed-specific tool, 0x15f/discover-
pagespeed-cloaking, is an engineering prototype tested on “50+ manually reviewed Shopify sites” —
useful for feature ideas, but platform-specific, small, and without a sampling frame. The strongest
adjacent science, Invernizzi et al.'s Cloak of Visibility (IEEE S&P 2016), proved
large-scale multi-profile cloaking detection is feasible — a labeled set of 94,946 URLs
at 95.5% accuracy and a 0.9% false-positive rate — but for search and
ad cloaking, and it stresses that benign personalization, geo and responsive design make naïve diffs
unsafe. Neither answers the PageSpeed prevalence question. That is the gap this work is built to close.
The pilot: a real lower bound on server-side UA cloaking
We took a fixed, citable sampling frame — the Tranco list Q2W74 (generated 2026-06-18), top 2,000 — and fetched each home page's raw HTML four times from the same egress IP, in an ABBA block: normal mobile user-agent, Lighthouse-marked user-agent, Lighthouse again, normal again. The bracketing matters. The two normal loads give an A/A control — how much a site differs from itself between two identical requests (ads, A/B buckets, randomized inventory). The Lighthouse pair gives the A/B signal. A real user-agent flip has to clear a site's own A/A noise to count, not just differ.
The decision thresholds are exactly those in our production
cloaking tool: a flip is material only if the
Lighthouse HTML is ≥25% lighter, or has ≥3 fewer <script> tags, or drops ≥2
third-party hosts (consent/CMP hosts excluded — Google permits hiding those for Lighthouse). A
candidate must additionally be directional (lighter for Lighthouse),
stable (both Lighthouse loads show it), and above this site's own A/A
noise. Every candidate is then read by hand for a benign explanation before it is allowed to
count.
The result is the empirical core of the pilot, and it is mostly a null: flipping to a Lighthouse user-agent moves the delivered HTML no more than a site moves against itself between two identical loads. The two distributions sit on top of each other, and almost nothing reaches the 25% materiality line.
Nine sites crossed a materiality threshold automatically. Every one was re-fetched and read by hand —
and zero survived as deceptive cloaking. Two were bot-protection serving the
Lighthouse user-agent a blank page or a “Client Challenge” (anses.gob.ar,
slideshare.net) — which hurts the score, the opposite of cloaking. Two were
dynamic rendering that handed Lighthouse the fuller prerendered page while
the normal user-agent got a “enable JavaScript” shell (roku.com, pluto.tv).
Two served the identical visible page in lighter markup (paloaltonetworks.com,
cdnvideo.ru). The remaining three (spotify.com, msn.com,
temu.com) handed the Lighthouse-marked agent a thin app shell — genuinely differential,
but their real content is client-rendered either way and no score-improving mechanism is in evidence,
so they stay suspicious, not confirmed. A further 12 reachable sites refused the Lighthouse
user-agent outright (bot defense, not score-gaming) and are counted as excluded.
So in 1,162 cleanly-measured top sites, confirmed server-side user-agent cloaking is 0 — a 95% upper bound of 0.26% (rule of three), with the three unexplained cases bounding the worst case at 0.55%. This is a floor, not the answer, and it says something specific: the crudest cloaking is essentially absent in the server layer of the head of the web. That is exactly the prediction that motivates a full census — the cheating, where it exists, lives in client-side JavaScript, IP and fingerprint branching, and the long tail, none of which a single raw fetch can reach. It also shows the harder problem in miniature: a naïve detector would have shipped nine false positives; careful controls and human review took it to zero.
Why “mostly null” is the right pilot result
A pilot that breathlessly “found cloaking everywhere” would be the warning sign. Real top sites run A/B tests, rotate ads, and localize — the A/A control quantifies that churn, and it is the reason a credible detector cannot be a naïve diff. The pilot's job is to prove the measurement machinery (fixed frame, paired profiles, controls, frozen thresholds, manual adjudication) works end-to-end and to bound the easy case. It does. The hard case needs the crawl below.
What a real census takes — the registered protocol
Scaling from “bluntest probe on 2,000 sites” to “defensible prevalence across the web” is not a matter of fetching more pages. It needs a design that survives an adversary and a skeptic. The full protocol — the preregistered analysis plan and labeling rules are in the pack below — is built on six load-bearing ideas.
A fixed frame, real browsers, paired profiles
A locked Tranco list ID/date as the denominator (CrUX origins as a sensitivity frame), and two version-locked profiles: a real Chrome (
REAL_CHROME) and a Lighthouse/PSI emulation (LH_PSI_EMU) harvested immediately before launch, because the fingerprint drifts.Randomized repeats and ablations
At least three paired runs per site in randomized ABBA/BAAB order across multiple countries and days, then one-factor-at-a-time ablations (UA only, UA-CH only,
navigator.platformonly, viewport only, egress IP only) so a positive can be attributed to a specific detector instead of guessed at.Five-layer feature extraction
Network (bytes by type, third-party, blocked requests), DOM/content (nodes, text shingles, similarity), visual (screenshot & perceptual-hash with consent zones masked), trace (LCP element geometry, TBT, layout shifts), and static/dynamic code (Lighthouse-string branches,
document.close, resource-blocking hooks).Preregistered materiality, frozen after a pilot
Directional thresholds set before the main run — total bytes ≥25% and 250 KB lighter; JS bytes ≥30% and 100 KB; third-party requests ≥50% fewer; DOM nodes ≥20% with content loss; text-shingle similarity <0.75 — then frozen, with main-census sensitivity to the thresholds reported.
A four-part confirmation rule + blinded humans
A confirmed positive is directional, stable in ≥2 of 3 runs, specific (A/A and B/B control diffs smaller than the A/B diff; an ablation localizes the feature), and backed by mechanism evidence. Two blinded reviewers label paired artifacts; a third adjudicates; report Cohen's κ and per-class precision.
False-positive-adjusted prevalence
No classifier is perfect, so the headline is corrected with the Rogan–Gladen estimator,
p_adj = (p_obs + Sp − 1) / (Se + Sp − 1), using the manual-validation sensitivity and specificity — with bootstrap/Bayesian intervals, not a plug-in CI.
And it has to be powered. The reason a pilot bounds rather than estimates is sample size: a credible prevalence with a tight interval needs tens of thousands of sites, not thousands.
Who this is for — and the ethics
The most important framing in this whole area: a store owner whose site cloaks PageSpeed is usually a victim, not a perpetrator. The pattern documented in the wild is a third-party “speed optimization” app or freelancer that installs detection-and-stripping to manufacture a green score — so the merchant pays for a number, not a faster store, and often doesn't know. That shapes both the disclosure protocol and the tooling.
- Check before you accuse. A high lab score with slow real users, or markup that changes for a Lighthouse user-agent, is a prompt to investigate — not proof of intent. Run the free PageSpeed cloaking test on a URL to see the evidence side by side.
- Disclose responsibly. The protocol notifies platforms and owners privately with minimal reproducible evidence, allows a 60–90 day remediation window, and publishes aggregate prevalence immediately — site-level details only for large platforms or after the window.
- Behavior, not intent. A public crawl rarely proves who commissioned a behavior. The census estimates what sites do, and says so — no accusations of motive.
- Measure the real thing. If your CrUX is poor but your lab score is perfect, the fix isn't a better trick — it's a real reduction in payload and main-thread work. That is what our savings-materialization study and a real audit are about.
Limitations — read before quoting
The pilot is a floor, by construction
It detects only server-side branching on the UA string that changes raw HTML. Client-side JS cloaking, IP/reverse-DNS cloaking, UA-Client-Hints branching, and render-time metric tricks are all invisible to it. The true prevalence of cloaking is at least the pilot's number and almost certainly higher.
One IP, one country, one window
All fetches leave from a single egress. Geographic and IP-based cloaking can't be seen from one vantage point; the full protocol uses multiple egress countries by design.
No prevalence number is claimed for “cloaking” overall
The pilot speaks only to the server-side-UA slice on the top 2,000. The population estimate the title asks for requires running the registered crawl; we deliberately do not extrapolate the pilot to “the web.”
The head of the web isn't the tail
Top sites are the least likely to cloak and the best instrumented. Prevalence almost certainly rises down-rank and on specific platforms — which is why the census stratifies by rank band and CMS.
Raw HTML ≠ rendered page
We measure delivered markup, a structural proxy. A real census renders and traces both profiles to catch metric-layer manipulation; that is in the protocol, not the pilot.
Data, code & sources
Everything needed to re-run the pilot and to execute the full census is published under CC BY 4.0: the fixed sampling frame, the pilot crawler, the registered analysis plan and labeling protocol, the precision tables, and the result-shell that lists exactly which tables must exist before any numeric prevalence claim.
Key sources
- GoogleChrome/lighthouse (2024). People detect Lighthouse to cheat its performance score (issue #15829) — the motivating technique catalogue.
- Invernizzi, L. et al. (2016). Cloak of Visibility: Detecting When Machines Browse a Different Web. IEEE S&P — 94,946 URLs, 95.5% accuracy, 0.9% FPR.
- 0x15f. Discover Pagespeed Cloaking — the closest PageSpeed-specific detector (50+ Shopify sites).
- Le Pochat, V. et al. (2019). Tranco: A Research-Oriented Top Sites Ranking Hardened Against Manipulation. NDSS — the sampling frame.
- Chrome for Developers. Lighthouse performance scoring (the v10 metric weights) & About PageSpeed Insights (lab vs field).
- Koshigoe, J. (2020). A perfect LCP with one line of code. DevisedLabs — an LCP-gaming primitive.
- Shopify (2024). A new web performance dashboard with real-user insights — platform move from lab Speed Score to field CWV.
Cite this study
PageSpeedAudit Research (2026). How many sites cheat PageSpeed? A registered
census protocol and user-agent-flip pilot for Lighthouse/PageSpeed Insights
cloaking. https://pagespeedaudit.com/research/how-many-sites-cheat-pagespeed
@misc{pagespeedaudit2026cloaking,
title = {How many sites cheat PageSpeed? A registered census protocol and
user-agent-flip pilot for Lighthouse/PageSpeed Insights cloaking},
author = {{PageSpeedAudit Research}},
year = {2026},
url = {https://pagespeedaudit.com/research/how-many-sites-cheat-pagespeed},
note = {Tranco-frame pilot + preregistered census protocol, CC BY 4.0}
}
Free 4-part email series
Score theater — the series behind this study
Four short emails, then it stops. The series lives in email only — it isn't published on the site:
- Part 1How fake scores are made — the incentive, the score arithmetic, the documented playbook.
- Part 2The five-minute fake-score check — lab vs field, Google's screenshot, the UA flip.
- Part 3What the top-2,000 pilot found — and why "mostly null" is the honest headline.
- Part 4What to do — whether the score is fake, or real but slow.
Worried a site is cheating its PageSpeed score?
Run the free PageSpeed cloaking test to compare what Google's PageSpeed Insights sees against what a normal visitor gets — the same probe this pilot runs at scale. For a real, code-level diagnosis of your field performance, a PageSpeedAudit report separates genuine fixes from score theater. See also whether the web actually got faster and whether Lighthouse's promised savings materialize.