Writing

Article

Why a perfect Lighthouse score can coexist with slow real users

A 100 in Lighthouse is one scripted load on a simulated device. Here is what that run cannot see, and why your field data in Search Console can still be failing.

A green 100 is satisfying and it is worth having. It is also a claim about one specific thing: a single scripted cold load of one URL, on one simulated device, over one simulated network, with no user in it.

Real visitors are a distribution of devices, connections, locations, entry points and behaviours. When a site scores 100 in the lab and still fails Core Web Vitals in the field, it is almost never because Lighthouse lied. It is because the question it answered was narrower than the question you cared about.

Here is what that run cannot see.

1. Nobody interacted

Lighthouse has no INP score. It cannot have one, because INP measures the latency of real interactions and a scripted load does not click anything.

What it reports instead is Total Blocking Time — main-thread blocking during load. That is a reasonable proxy for the load-time half of the problem, and a site with high TBT will have INP trouble. But a 0 ms TBT tells you the page was quiet while it loaded. It says nothing about the filter panel, the menu, the carousel or the modal, none of which the run ever opened. Interaction cost that lives in components a scripted load never touches is invisible to the score.

2. The simulated device is one point on a curve

The mobile preset simulates a mid-range Android on a throttled connection. Your audience contains phones considerably slower than that, on networks considerably worse, and Core Web Vitals is assessed at the 75th percentile — it is explicitly designed to notice the slowest quarter of your visits. A single simulated device cannot represent a distribution, and the point of the percentile is the tail.

3. Only one URL was tested

Almost everyone runs Lighthouse on the homepage. The homepage is usually the most optimised page on the site, and often the least visited.

Field data in Search Console groups URLs and reports on the group. Your product pages, your search results, your paginated listings and your blog templates are in there, and they may share none of the homepage’s careful work.

4. Third parties behave differently for real people

A lab run may be geo-located somewhere your tag manager loads a smaller configuration, may not fire consent-gated scripts because there is no consent dialogue to accept, may be excluded from A/B tests, and will not trigger anything keyed to a returning-visitor cookie.

Real users accept the banner, get bucketed into experiments, and receive the chat widget, the heatmap recorder and the retargeting pixel. That is a different page from the one that scored 100.

5. Layout shift accumulates over a visit

CLS is cumulative across the life of the page. A run that stops after a few seconds and never scrolls cannot see the ad slot that resizes below the fold, the lazy image without dimensions the user scrolls past, or the sticky banner that appears after 10 seconds.

6. Real navigation is not always a cold load

Lighthouse loads one URL cold, with an empty cache. Real sessions include repeat visitors with a warm cache, back-forward navigations, and — on a client-routed site — soft navigations that skip the document request entirely and are measured differently from what your lab run did.

7. Your origin is fast when only you are asking

A single lab request hits a server with no load. Real traffic arrives in bursts, against caches that miss, databases under contention, and origins that are fine at one request per second and not at a hundred. TTFB measured once by one client is not TTFB under your actual traffic.

8. The lab run is now; the field is 28 days

The Chrome UX Report aggregates over a rolling 28-day window. A fix you deployed last week is diluted by three weeks of the old page. This cuts both ways: your green lab score today may be describing a page that field data will not fully reflect for a month, and a regression you shipped yesterday is not visible yet.

What to do about it

None of this makes lab testing useless. It makes it the wrong thing to stop at.

I publish lab numbers for my own sites for that reason, and I label them as lab numbers: protectorguardrail.com, Lighthouse 12 on the mobile preset, measured 5 August 2026. They are re-runnable, which makes them a checkable claim rather than an assertion. What they are not is a statement about what every visitor to those sites experienced — for that you need the field, and it is worth being clear about the difference.

Alfred Westerveld