performance

Core Web Vitals: what to measure and what to actually fix

Lab scores and field data measure different things, and only one of them counts for ranking. What each metric means, what causes bad ones, and which fixes are worth the effort.

Core Web Vitals are three numbers Google uses to describe how a page feels to the person waiting for it. They are a ranking signal — a modest one, well below relevance — and a genuinely useful diagnostic, provided you measure them from real visitors rather than from a test.

The three metrics

Largest Contentful Paint (LCP) — when the largest element in the viewport finished rendering. It approximates "when did the page look ready". Good is under 2.5 seconds; poor is over 4.

Interaction to Next Paint (INP) — across the whole visit, how long the page took to visually respond to interactions, reported at roughly the worst case. It replaced First Input Delay in 2024 because FID only measured the delay before handling began, which flattered pages that started work quickly and then blocked for a second. Good is under 200ms; poor is over 500ms.

Cumulative Layout Shift (CLS) — how much visible content moved unexpectedly during the page's life. It is the metric behind the experience of reaching for a button that jumps away. Good is under 0.1; poor is over 0.25.

Two supporting metrics are worth having beside them: Time to First Byte (TTFB), which is your server and network before rendering can begin at all, and First Contentful Paint (FCP), when anything at all appeared.

Lab data and field data are not the same thing

This is the distinction that wastes the most time.

Lab data — Lighthouse, PageSpeed Insights' lab section, WebPageTest — runs your page once, on a simulated device, on a simulated connection, from one location. It is repeatable and excellent for debugging, because you can change something and see the effect immediately.

Field data — the Chrome User Experience Report, and any real-user monitoring you run yourself — is what actual visitors experienced, on their actual devices and connections. It is what Google uses for the ranking signal, reported at the 75th percentile of your traffic.

They diverge, sometimes wildly. A page that scores 98 in Lighthouse can have poor field LCP because real visitors are on older phones over mobile networks, several timezones from your origin. The lab score is a hypothesis; the field data is the result. Optimise against the field data and use the lab to test changes.

The 75th-percentile detail matters too: you are being judged by the experience of your slower quarter, not your median. Improving the fastest three quarters of your traffic changes nothing.

What actually causes bad scores

Poor LCP is nearly always one of four things: a slow server response (fix TTFB first — nothing renders before it), a hero image that is too large or loaded lazily when it is above the fold, render-blocking CSS or fonts in the head, or a client-side framework that renders the main content only after its JavaScript has downloaded and executed.

Poor INP is almost always the main thread being busy. Long tasks from analytics scripts, tag managers, chat widgets, A/B testing tools and consent banners — usually several at once. This is where third-party scripts do their real damage: each one is small on its own, and together they occupy the thread the browser needed to respond to a tap.

Poor CLS is images and iframes without dimensions, web fonts swapping and reflowing text, content injected above existing content — banners, cookie notices, late-loading ads — and animations of properties that trigger layout rather than transform and opacity.

The fixes, ranked by return on effort

  1. Set explicit width and height on every image and iframe. Fixes most CLS. Costs an afternoon.
  2. Audit third-party scripts and remove what nobody reads. Usually the single largest INP improvement available, and it is free — it is deletion, not engineering. A cookie banner removed for compliance reasons also removes a render-blocking script and a layout shift.
  3. Preload the LCP image and never lazy-load it. loading="lazy" on the hero image is a common and self-inflicted wound.
  4. Serve fonts from your own origin with font-display: swap and preload the one used above the fold.
  5. Cache HTML at the edge. TTFB is the floor under LCP, and an edge cache removes the round trip to origin entirely.
  6. Break up long JavaScript tasks, and defer anything not needed for first render.

Measure it on your own site

CrUX only reports on pages with enough traffic, which excludes most individual pages of most sites. If you want per-page field data, you have to collect it yourself.

The browser gives it to you directly. PerformanceObserver reports LCP, CLS and interaction timings without any library, and a few lines of code can send them to wherever your analytics lives. If your analytics tool collects Core Web Vitals natively, you get the numbers segmented by page, country and device — which is where the real finding usually is.

That segmentation is the point. An aggregate LCP of 3.1 seconds tells you nothing actionable. "LCP is 1.9s on desktop and 5.4s on mobile in Brazil" tells you exactly which image to fix and for whom.

Keeping it honest

  • Compare like with like: a metric measured on your traffic is not comparable to a competitor's Lighthouse score.
  • Watch the 75th percentile, not the average. Averages hide the tail that is being measured.
  • Annotate deployments on the chart. A regression you cannot date is a regression you cannot attribute.
  • Remember the ranking weight is small. Core Web Vitals are a tiebreaker between comparable results, not a substitute for pages that answer the question someone asked.

Common questions

What are good Core Web Vitals scores?

Largest Contentful Paint under 2.5 seconds, Interaction to Next Paint under 200 milliseconds, and Cumulative Layout Shift under 0.1 — each measured at the 75th percentile of real visits. Above 4 seconds, 500 milliseconds and 0.25 respectively is considered poor.

Why is my Lighthouse score good but my field data bad?

Lighthouse runs once on a simulated device and connection from a single location, while field data reflects real visitors on real hardware and networks, reported at the 75th percentile. A page can score highly in the lab and still be slow for the slower quarter of actual traffic. Field data is what counts for ranking.

Do Core Web Vitals affect search rankings?

Yes, as part of the page experience signals, but the weight is modest. They act as a tiebreaker between results of comparable relevance rather than as a substitute for content that answers the query.

What is the fastest way to improve Interaction to Next Paint?

Remove third-party scripts. INP is dominated by long tasks occupying the browser's main thread, and tag managers, chat widgets, A/B testing tools and consent banners are usually the largest contributors. Deletion is faster and more effective than optimising the code around them.