$ flowproject.agency / blog · [notes · engineering + AI + marketing]
Bp/00:00:00 HUEN
$ cat core-web-vitals-in-practice.md

Core Web Vitals in practice: INP, LCP and CLS

Core Web Vitals are three metrics: LCP measures loading (good is 2.5 seconds or less), INP measures responsiveness (good is 200 ms or less) and CLS measures visual stability (good is 0.1 or less), all assessed at the 75th percentile of real visits. Google's ranking systems do use them, but they don't trump relevance. On a small business site, the biggest wins almost always come from the same three places: server response time, the hero image and third-party scripts.

Plenty of clients come to us saying "PageSpeed shows 54, get it to 100." We think that's the wrong goal. The Lighthouse score is a lab score, and Google looks at real-user data. Below is what's actually worth measuring, and the order we fix things in.

  • Three thresholds: LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1, for 75% of visits, with mobile and desktop assessed separately.
  • Field data is what counts (Chrome UX Report, rolling 28-day window), not the 0–100 Lighthouse score.
  • A ranking signal, not the deciding one: Google still favours relevant content even when page experience is weaker.
  • For LCP, split the time into four parts and fix whichever is biggest.
  • For INP, the usual suspects are chat widgets, scripts piled into the tag manager and heavy event handlers.
  • For CLS, missing image dimensions, cookie banners and web fonts cause most of the jumping.

What do the three metrics measure, and what counts as good?

Google sets the thresholds on the Core Web Vitals page on web.dev. A page passes when at least 75% of visits land in the good range on all three metrics.

MetricWhat it measuresGoodNeeds improvementPoor
LCP (Largest Contentful Paint)when the largest element in the viewport is rendered≤ 2.5 s2.5–4 s> 4 s
INP (Interaction to Next Paint)the time from a click, tap or key press to the next frame, based on the slowest interactions during the visit≤ 200 ms200–500 ms> 500 ms
CLS (Cumulative Layout Shift)how much content moves around unexpectedly≤ 0.10.1–0.25> 0.25

INP replaced FID on 12 March 2024. That matters because FID only measured the delay of the first interaction, while INP covers the whole visit. Lots of sites that sailed through on FID started failing on INP, especially on mobile.

Which number should you watch: the Lighthouse score or field data?

Field data. The Chrome UX Report (CrUX) collects measurements from real Chrome users over a rolling 28-day window; that's what you see at the top of PageSpeed Insights and in the Search Console Core Web Vitals report. Lighthouse (and the 0–100 section lower down in PageSpeed Insights) is a single simulated load on a fixed device profile. It's excellent for debugging, but it doesn't describe reality. The two often disagree, and when they do, field data wins.

Two practical consequences:

  • A Lighthouse page-load test can't measure INP, because nobody interacts with the page. In the lab, Total Blocking Time (TBT) is the closest proxy: it flags the problem but doesn't measure the same thing.
  • Low-traffic sites often have no CrUX data. Then you need your own measurement: with Google's open-source web-vitals library, a few lines of code send real values to your analytics, and the attribution build even tells you which element or interaction caused a bad score.

How much do they matter for rankings?

According to Google's Search Central documentation, Core Web Vitals are used by its ranking systems, and Google recommends achieving good scores. Its page experience guidance is equally clear, though: Google tries to show the most relevant content even when page experience is sub-par, and good scores alone don't guarantee top rankings.

Our take: Core Web Vitals are a tie-breaker, not an engine. A thin page won't climb just because it's lightning fast. Slowness, however, shows up directly in conversions: a visitor staring at a white screen for three seconds, or tapping an "Add to cart" button that ignores them for half a second, doesn't wait around. That's why we measure and fix, not for the score. We covered the rest of technical SEO in our technical SEO article.

How do you improve LCP with real numbers?

Split the time into four parts

The web.dev LCP optimisation guide breaks LCP into four subparts:

  1. Time to First Byte (TTFB): when the first byte of HTML arrives.
  2. Resource load delay: how long the browser waits before it starts downloading the LCP image.
  3. Resource load duration: the download itself.
  4. Element render delay: the gap between the download finishing and the element appearing.

This breakdown turns the work into arithmetic. The 2.5-second budget is shared: if TTFB at the 75th percentile is 1.2 seconds, the other three get 1.3 seconds between them. Compressing the image won't save you; fix the server first. If TTFB is fine but the image only starts loading halfway through, the delay is the problem, not the file size. The Performance panel in Chrome DevTools shows all four subparts for the LCP element.

What we find on almost every small business site

  • Slow TTFB: WordPress without caching, overloaded shared hosting, a pile of plugins. Page caching and a CDN usually deliver more than any image optimisation.
  • A lazy-loaded hero image: loading="lazy" is for images below the fold, never for the LCP image.
  • A late-discovered image: if the hero is a CSS background or injected by JavaScript (a slider, say), the browser finds it late. Make it a plain <img> in the HTML with fetchpriority="high".
  • Oversized images: a 2,400-pixel JPEG on a 400-pixel phone screen. You need srcset, sizes and a modern format (WebP, AVIF).
  • Render-blocking CSS and fonts: an entire theme's CSS loading before the first paint.

How do you improve INP?

INP splits each interaction into three phases: input delay (the browser is busy with something else), processing time (event handlers run) and presentation delay (painting the next frame). According to the web.dev INP guide, the main enemy is the long task, anything running over 50 ms, during which the main thread can't respond.

The usual culprits on small business sites:

  • Third-party scripts: a chat widget, a heatmap tool, several analytics and ad tags in one tag manager. All of them run on the main thread. Our first step is always an inventory: what's installed, and who still needs it.
  • Heavy event handlers: in a webshop, a filter that re-renders the whole product grid on every click, or an "Add to cart" button that fires five analytics calls before updating the UI.
  • An oversized DOM: mega menus, hidden mobile layouts, endless product lists. The more elements there are, the more expensive every re-render becomes.

The fix: give visual feedback first and defer the rest (break up long tasks and yield back to the browser), and load non-critical scripts later or on interaction. In custom builds we design for this from day one; on template-based platforms, removing one or two plugins is often worth more than any fine-tuning.

How do you improve CLS?

The web.dev CLS guide names images without dimensions, late-injected content and web fonts as the most common causes. In practice:

  • Give every image and embed width and height attributes (or a CSS aspect-ratio) so the browser reserves the space up front.
  • Don't let the cookie banner or promo bar push content down: overlay it, or reserve its space in advance.
  • Fonts: match the fallback font's metrics to the web font (size-adjust and friends) so the font swap doesn't reflow the lines.
  • Animate with transform, not by changing top or height.

In what order should you tackle it?

  1. Search Console, Core Web Vitals report, mobile view. Which URL group fails, and on which metric?
  2. One representative URL in PageSpeed Insights. Field data at the top (what's wrong), lab data below (why).
  3. One metric at a time, starting with the worst. For LCP, use the four-part breakdown; for INP, the long tasks and the script inventory.
  4. Verify in the lab before deploying, on the same device profile.
  5. Be patient. Because of the 28-day CrUX window, a fix takes roughly a month to show fully; until then, your own web-vitals data tells you whether you're heading the right way.

Frequently asked questions

Do I need a Lighthouse score of 100?

No. Google looks at field data, and there the three thresholds are what matter. A page with a lab score of 80 that passes all three metrics for real visitors is in good shape.

Why does PageSpeed Insights show no field data?

Because the page or URL doesn't have enough Chrome visits in the 28-day window. Search Console may then report a value for a group of similar URLs or the whole origin; for an accurate picture, measure it yourself with the web-vitals library.

Which matters, desktop or mobile?

Google assesses both separately. On small business sites, mobile is almost always the weaker one: slower processors, worse networks. We start with mobile.

Will a speed plugin fix it?

Partly. Caching and image compression help LCP a lot. They rarely improve INP, though, because that depends on how much script runs and how well the code is written, and overly aggressive script delaying can even make interactions worse.

If you're not sure which metric your site fails on and why, request our free SEO and AI visibility audit; Core Web Vitals are part of it. And if the problem lives in the system rather than the settings, in our webshop development and custom software development work we design for performance from the first line of code.

FlowProject Kft.
Independent digital studio · Budapest

Got a project that needs engineering + AI + marketing under one roof?

let's_talk() →

← back to blog