The three metrics, and what they punish
Core Web Vitals reduce page experience to three numbers. Each one corresponds to a distinct kind of frustration, which is why improving one rarely improves the others.
| Metric | Measures | Good | Needs work |
|---|---|---|---|
| LCP | Time until the largest element paints | under 2.5s | over 4.0s |
| INP | Delay between interaction and visible response | under 200ms | over 500ms |
| CLS | How much the layout jumps while loading | under 0.1 | over 0.25 |
One thing to settle before you start: Google scores you on field data from real visitors, not on your Lighthouse run. A perfect lab score on a fast laptop with fibre tells you very little about a user on a mid-range Android phone on a congested mobile network. Check Search Console for the field numbers.
LCP: make the biggest thing arrive sooner
LCP is almost always a hero image, a heading, or a background image. The first step is to find out which, because optimising the wrong element wastes the effort entirely. Chrome DevTools marks the LCP element in the Performance panel.
Once identified, LCP breaks into four parts: server response, resource discovery, resource download, and render delay. Attack them in that order.
- Cut server response time — cache HTML at the edge, or serve static HTML where the page does not need to be dynamic
- Preload the LCP image with
<link rel="preload" as="image" fetchpriority="high">so the browser starts it without waiting to parse CSS - Never lazy-load the LCP image;
loading="lazy"on a hero image is one of the most common self-inflicted LCP problems - Serve modern formats and correct dimensions — a 3000px-wide JPEG scaled into a 600px slot wastes most of its bytes
- Get render-blocking CSS off the critical path, and load fonts with
display: swapso text is never invisible while a font downloads
INP: stop blocking the main thread
INP replaced First Input Delay in 2024 and is considerably harder to satisfy, because it measures every interaction across the visit rather than just the first one. A page can feel fine on load and still score badly if a filter or accordion takes half a second to respond.
The cause is nearly always JavaScript occupying the main thread when the user taps. The browser cannot paint a response until the current task finishes, so a single 300ms task is enough to fail.
- Audit third-party scripts first — chat widgets, tag managers and analytics are usually the largest offenders and the easiest to defer
- Break long tasks up so no single block of work exceeds about 50ms
- Yield to the browser between chunks of work rather than looping through a large array in one pass
- Give visual feedback immediately on tap, then do the heavy work — perceived responsiveness is what is being measured
- Prefer CSS transitions to JavaScript-driven animation wherever the effect allows it
CLS: reserve the space before you fill it
CLS is the most fixable of the three, and the fixes are almost mechanical. Layout shifts happen because something arrives late and pushes existing content out of the way.
- Put
widthandheightattributes on every image and video so the browser reserves the box before the file arrives - Give ad slots, embeds and iframes a fixed minimum height
- Never insert banners or notices above existing content after load; reserve the space or overlay it
- Preload web fonts and pick a fallback with similar metrics so the swap does not reflow paragraphs
- Animate
transformandopacityrather than properties that trigger layout
Changes that look productive but are not
A few interventions get recommended constantly and rarely move the numbers.
- Minifying already-gzipped CSS and JS — the saving is usually a rounding error next to a single unoptimised image
- Switching CSS frameworks without removing the unused rules that caused the weight
- Adding a caching plugin on top of an unresolved slow database query
- Chasing a Lighthouse score of 100 on desktop while the mobile field data stays red
A working order of operations
When we take on a performance engagement, the sequence is consistent because it front-loads the cheapest wins.
- Pull field data from Search Console and identify which metric is actually failing, and on which templates
- Reproduce on a throttled mobile profile rather than a desktop connection
- Fix images: format, dimensions, preload the hero, lazy-load everything below the fold
- Remove or defer third-party scripts that are not needed for first render
- Add explicit dimensions everywhere to close out CLS
- Re-measure after 28 days, because field data is a rolling window and will not update immediately
What good looks like in practice
For a content or brochure site, all three metrics in the green is a realistic target and mostly a matter of discipline. For a heavy e-commerce or dashboard product it takes real engineering, and the honest goal is often "green on LCP and CLS, acceptable on INP" while interaction work continues.
Worth keeping in perspective: Core Web Vitals is a modest ranking factor, not a dominant one. It rarely outranks better content. Its stronger effect is on conversion, where slow pages lose people before they ever reach the form.
Not sure which metric is hurting you?
Our technical SEO audit reads your real field data, identifies which templates fail and why, and returns a prioritised fix list with effort estimates against each item.