Why is our site slow? Core Web Vitals, INP and real user data
Most site speed arguments are held over the wrong number. What Google looks at is not the 0-100 score Lighthouse prints, it is field data collected from Chrome users who actually visited your pages. There are three metrics: LCP for loading, INP for responsiveness, CLS for visual stability. The "good" thresholds are 2.5 seconds, 200 milliseconds and 0.1. They are evaluated at the 75th percentile rather than the average, which means three quarters of your users have to land under those values, and you have to clear all three at once. The 95 you saw on your own laptop has little to do with it.
Lab data and field data are not measuring the same thing
Lighthouse is a lab test: one device, one throttled connection, one location, one page load. That control is what makes it useful for diagnosis and useless as a verdict. Your actual audience includes five-year-old Android phones, office fibre, and someone on three bars in a lift.
Field data comes from the Chrome User Experience Report (CrUX). The dataset refreshes daily, but every measurement is computed over a rolling 28-day window, which stops a single bad day from flipping the picture. Pages with enough traffic get URL-level data; pages without it quietly fall back to the origin. If PageSpeed Insights tells you there is not enough real-user data for a URL, the number on that screen belongs to your whole site, not to the page you were investigating.
The gap shows up metric by metric. INP cannot be measured in a lab at all, because no script can predict when or how a real person will interact with the page, so Lighthouse substitutes Total Blocking Time as a proxy. CLS diverges too: a lab run only captures shifts during initial load, while field data counts every unexpected shift across the visit, including the ones lazy-loaded content causes while a user scrolls. Lab tools tell you why. Field data decides whether you passed.
Three metrics, six thresholds
LCP is good under 2.5 seconds and poor above 4. INP is good at or under 200 milliseconds and poor above 500. CLS is good at or under 0.1 and poor above 0.25. Everything in between is flagged "needs improvement" and does not count as a pass. Mobile and desktop are assessed separately.
INP replaced FID in March 2024 and that swap made most report cards harsher. FID only measured the delay before the browser could begin running an event handler on the first interaction, which is the easy part. INP looks at interactions throughout the visit and counts the whole path from the click to the frame that shows the result. It is the first of these metrics that genuinely measures how your code responds.
The metric you are failing is almost certainly LCP
The 2025 Web Almanac from HTTP Archive, using July 2025 data, puts it plainly: 48% of origins pass all three metrics on mobile and 56% on desktop. Broken out on mobile, 81% pass CLS, 77% pass INP, and 62% pass LCP. One metric is doing most of the failing.
That answers the prioritisation question for you. If your assessment is red, loading is where to look first, and fixing it can carry you over the line without touching the other two.
Do not try to fix LCP before you split it into four parts
LCP is not one event, it is the sum of four subparts: time to first byte, the delay before the LCP resource starts loading, the time the resource itself takes to arrive, and the delay between the resource finishing and the pixels appearing. In a healthy distribution TTFB and resource load duration take roughly 40% each, and the two delays stay under 10%. The time should go into downloading the HTML and the actual image, not into waiting.
When you measure and find the delays are bloated, the causes are predictable. The LCP element is an image on 76% of mobile pages and 85.3% of desktop pages, so that image has to be discoverable in the initial HTML. A hero injected later by JavaScript, or declared as a CSS background, hides from the browser's preload scanner. It gets worse: the Almanac found roughly 16-17% of pages lazy-load their LCP image, deliberately delaying the one thing that should appear first. Meanwhile fetchpriority="high" appears on only 17% of mobile pages that have an LCP image, up from 15% in 2024.
Work in this order. Make the LCP resource discoverable and drop the lazy-loading, then clear render-blocking CSS and JavaScript, then shrink the resource itself (modern format, correct dimensions, a CDN), and only then go after TTFB. Starting with server-side optimisation is usually the most expensive move with the least return.
INP is not a network problem, it is a main thread problem
An interaction has three phases: input delay (the user tapped, but the main thread was busy with something else), processing duration (your event handlers running), and presentation delay (the browser painting the next frame). If those three add up past 200 milliseconds, the interface feels stuck.
The culprits repeat. Large JavaScript bundles evaluated during startup create long tasks, and every tap that arrives during one waits in a queue. Code that reads a style and immediately writes one forces the browser into synchronous layout. An oversized DOM inflates the work done on every frame. The remedies are equally well known: break work in event handlers into separate tasks and yield to the main thread, defer non-critical updates until after the next paint, batch DOM reads and writes, and use content-visibility for off-screen sections.
There is a hardware dimension too. INP is bounded by CPU, not bandwidth, so a problem that never surfaces on a developer laptop shows up instantly on a mid-range Android phone. Do not pick your test device from the best handset on the team.
CLS is the cheapest win and the most neglected
Layout shifts come from almost the same short list every time: images without declared dimensions, ad and embed slots with no reserved space, components injected after load, and text reflowing when a web font swaps in. The Almanac data shows how common the neglect is. On mobile, 62% of pages have at least one image with no explicit dimensions, 87% use web fonts, and 40% run non-composited animations that can trigger layout.
The fixes are a few hours of work. Give images width and height, or set aspect-ratio in CSS. Reserve space for ads and iframes with min-height. Preload critical fonts and choose your font-display behaviour deliberately. Animate with transform instead of top and left, since transforms do not trigger layout.
One related win gets skipped constantly: the back/forward cache. If your page is eligible, the browser restores it from memory on a back navigation and that trip becomes effectively instant. Check the blockers. The Almanac still finds unload handlers on 11% of desktop pages and 10% of mobile ones, while Cache-Control: no-store climbed from 21% in 2024 to 23%. On most sites both are leftovers from habit rather than requirements.
Keep the ranking claim honest
Google's own documentation puts two sentences side by side: "There is no single signal. Our core ranking systems look at a variety of signals that align with overall page experience," and "Core Web Vitals are used by our ranking systems." The same page states that Google aims to surface the most relevant content even when page experience is sub-par.
The practical reading follows from that. Speeding up a page that is not relevant will not move it onto the first page. But in a competitive query where two results are close on content, performance can decide the order. Treat it as something you build on top of good content, not as a substitute for it.
The business case has actually been measured
Rakuten 24 optimised a single landing page for Core Web Vitals and ran a month-long A/B test with traffic split evenly, where performance was the only difference between the two versions. Revenue per visitor rose 53.37% and conversion rate rose 33.13%. Vodafone Italy improved LCP by 31% on a landing page and reported 8% more total sales. iCook improved CLS by 15% and saw a 10% lift in ad revenue.
Be careful quoting those figures in a proposal. Each was measured on a specific page, in a specific market, from a specific starting point. A site that is already fast will not see the same multiples. The useful move is to copy the method rather than the numbers: one page, one change, split traffic, measured result.
Put the measurement inside your pipeline
Three layers work together here. For real user monitoring, add Google's web-vitals library and send the metrics to your own analytics, so you can read your own 75th percentile without waiting on CrUX's 28-day window. For regression control, run Lighthouse in the pipeline and set a bundle size budget that fails the build when it is exceeded. For the long-term view, Search Console's Core Web Vitals report is enough, since it shows you the data Google is acting on.
Expect the lag and plan around it. When you ship a fix, your own instrumentation moves within days, while CrUX-based reports only reflect it fully once the rolling window turns over. Do not revert a good change because Search Console is still red two weeks later. Wiring these checks into the pipeline rather than running them by hand is covered in our post on CI/CD for small teams.
What fits into this week
Four tasks. First, run your five highest-traffic pages through PageSpeed Insights and read only the field data section at the top, ignoring the lab score. Second, identify the LCP element on each of those pages and confirm it is discoverable in the HTML and not lazy-loaded. Third, give every above-the-fold image an explicit size or aspect ratio. Fourth, add the web-vitals library so the next round of this discussion happens over your data instead of your impressions.
Some performance problems do not close with individual fixes, because the source is architectural or the accumulated weight is the real issue. Once you hit that point the decision moves elsewhere: measuring and prioritising that load is covered in our post on technical debt, and the choice between rewriting and modernising incrementally in legacy rewrite vs incremental modernisation.
Need help with this topic?