Core Web Vitals get treated as three numbers to make green. That framing produces a lot of work and not much benefit, because two of the three are usually fine and the third is usually caused by something a performance plugin cannot touch.
This covers what each metric actually measures, what genuinely moves it, and — the part most guides skip — the honest limit of what fixing them achieves.
The honest limit, first
Core Web Vitals are a small ranking factor. Google has said so repeatedly, and the behaviour of search results supports it: a fast page about the wrong thing does not outrank a slower page that answers the query.
They function as a tie-breaker. Where two pages are similarly relevant and similarly authoritative, the better experience can win. That is a real advantage, and it is a narrow one.
The stronger argument is commercial. Visitors abandon slow pages, mis-click shifting layouts, and leave forms that feel unresponsive. Those costs are immediate and measurable in your own analytics, and they apply to every visitor regardless of where they came from.
So: fix them because they cost you customers, not because they will rescue rankings. If the ranking problem is relevance, no amount of performance work will address it — and time spent here is time not spent on the actual constraint.
The three metrics
| Metric | Measures | Good | Usual cause when bad |
|---|---|---|---|
| LCP | Time until the largest visible element renders | < 2.5s | Slow server response, unoptimised hero image, render-blocking resources |
| CLS | How much the layout moves during load | < 0.1 | Images without dimensions, injected banners, late-loading fonts |
| INP | Delay between interaction and visible response | < 200ms | Heavy JavaScript on the main thread, third-party scripts |
All three are assessed at the 75th percentile of real visits. That detail matters more than it looks: an average lets a fast median hide a slow quarter, and the slow quarter is the one that leaves.
Largest Contentful Paint
LCP is usually the one that fails, and it is usually misdiagnosed as a JavaScript problem when it is a server or image problem.
Break it into its parts before optimising anything. LCP is the sum of:
- Time to first byte — how long the server takes to respond
- Resource load delay — how long before the browser starts fetching the LCP element
- Resource load time — how long that element takes to download
- Render delay — how long between download and paint
Measure which part dominates. Optimising images when the problem is a 1.2-second server response is effort spent on the wrong quarter of the number.
What actually moves it:
- Server response. Caching, a CDN, and not doing expensive work per request. Statically generated pages effectively eliminate this component
- The LCP image itself. Correctly sized, modern format, and not lazy-loaded — lazy-loading the hero image is a common own goal that delays the very element being measured
- Preloading the LCP resource so discovery is not gated behind CSS parsing
- Removing render-blocking resources in the head
What rarely moves it: minifying JavaScript, deferring analytics, or a plugin's "optimise" toggle. Those help elsewhere.
If LCP is dominated by server response rather than assets, the fix is architectural rather than a settings change — which is
the technical work that usually fixes it.Cumulative Layout Shift
The cheapest of the three to fix and the most irritating to experience. Almost every cause is a browser being unable to reserve space for something that arrives later.
The fixes are mechanical:
- Width and height on every image, so space is reserved before it loads. Aspect-ratio boxes achieve the same thing
- Reserve space for anything injected — banners, consent notices, ad slots. A cookie banner that pushes the page down on arrival is a classic
font-display: swapwith a matched fallback metric. Swapping to a font with different metrics reflows the text. Matching the fallback's size largely removes it- Never insert content above existing content after load, unless it is in response to a user action
CLS is worth fixing even at a good score, because it is the metric visitors consciously notice. Nobody times your LCP; everybody notices a button moving as they reach for it.
Interaction to Next Paint
INP replaced First Input Delay and is meaningfully harder, because FID measured only the first interaction's delay while INP measures roughly the worst full response across the visit.
A page can pass FID comfortably and fail INP, which is why sites that were green suddenly were not.
What moves it:
- Less JavaScript on the main thread. The main lever, and the least convenient
- Break up long tasks. Anything over 50ms blocks response to input; yield between chunks of work
- Audit third-party scripts ruthlessly. Chat widgets, heatmaps, tag managers and A/B testing tools are common culprits, and each is usually defended by someone
- Avoid layout thrash — reading and writing layout properties in the same frame forces synchronous recalculation
- Server-render what does not need interactivity. Hydrating a component that will never be clicked is pure cost
Third-party scripts are the recurring theme. Each is individually defensible and collectively fatal. The useful question is not "is this script slow" but "what does this script earn, and would we notice if it were gone".
Measuring properly
| Tool | Data | Use for |
|---|---|---|
| Search Console — Core Web Vitals | Field, 28-day rolling | The signal Google actually uses. Start here |
| CrUX / PageSpeed Insights | Field + lab | Field data by URL group |
| Lighthouse | Lab only | Diagnosing causes, never for judging pass/fail |
| Web Vitals JS library | Your own field data | Real-time monitoring on your own analytics |
Field data is the one that counts. Lighthouse on a fast laptop over a fast connection tells you almost nothing about a mid-range Android phone on mobile data, which is a large share of real visits. A green Lighthouse score alongside a failing Search Console report is not a contradiction — it means the lab conditions were optimistic.
Change one thing, then re-measure in the field. Field data updates on a 28-day rolling window, so improvements appear gradually rather than immediately. Judging a fix by the next day's number will mislead you.
One caveat about your own testing. If your checks append a cache-busting query string, they measure the origin rather than what a visitor receives. We ran that configuration for weeks and it hid a stale homepage entirely — the full account of that incident documents how a site can pass every automated check while serving a build from a week earlier.
When this is not your problem
Three situations where performance work is the wrong priority:
- Your pages are not ranking at all. Core Web Vitals decide close contests. If you are not in the contest, relevance and authority are the constraint
- All three metrics already pass in field data. There is no additional ranking benefit for being further under the threshold. Improving 1.9s to 1.4s is a UX decision, not an SEO one
- The site is largely static and already fast. Diminishing returns arrive quickly, and the next hour is better spent on content
The most common failure here is spending a month reaching perfect scores on a site whose actual problem is that it has six pages and no topical depth.
Want this handled properly?
You now know what the work involves. If you would rather not do it yourself, that is what we do.