What the three metrics measure
| Metric | Measures | Good | Needs work | Poor |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | Time to render the largest above-the-fold element. | ≤ 2.5 s | ≤ 4.0 s | > 4.0 s |
| INP (Interaction to Next Paint) | Worst-case time from user input to the next paint. | ≤ 200 ms | ≤ 500 ms | > 500 ms |
| CLS (Cumulative Layout Shift) | Total unexpected layout shift over the page lifecycle. | ≤ 0.1 | ≤ 0.25 | > 0.25 |
Targets are the 75th-percentile of real user samples (CrUX dataset). A page passes Core Web Vitals only when all three metrics meet “good” at that percentile.
INP replaced FID (First Input Delay) as the responsiveness metric in March 2024 (web.dev INP migration guide). INP is stricter — it measures the worst interaction, not the first.
Why they matter
Since 2021 Google has folded Core Web Vitals into the search ranking signal as part of “Page Experience”. The boost is modest — about a 3% rank uplift on average from a passing Core Web Vitals score, per Google’s own documentation and independent analyses. The penalty for failing is more relevant: pages that fail any vital lose visibility in competitive queries.
About 40% of mobile pages on the HTTP Archive 2024 dataset pass all three vitals. Desktop pass-rate is about 58%.
LCP: the largest element
LCP measures the time from navigation start to the moment the largest visible block renders. The “largest” element is typically:
- A hero image, when present.
- A block of headline text.
- A featured video poster.
What helps LCP:
- Pre-load the LCP candidate with
<link rel="preload" as="image" fetchpriority="high">for hero images. - Render-blocking resources removed. Inline critical CSS; defer non-critical JS.
- Modern image formats. AVIF and WebP per /html/picture cut bytes by 40–60%.
fetchpriority="high"on the LCP image (cross-engine since 2024).- Server-side rendering for first paint when JS-driven layout would otherwise delay the LCP element.
Median LCP improvement from fetchpriority="high" on the LCP
image is about 0.5 s on real-world sites per the Chrome 2023 study.
INP: responsiveness under interaction
INP measures the duration of the longest single user interaction during the page’s lifetime. Each interaction is the worst of input delay + processing + presentation.
What hurts INP:
- Long synchronous JavaScript handlers.
- Layout thrash inside the handler.
- Heavy work in
requestAnimationFramecallbacks scheduled by the handler. - Third-party scripts (analytics, ads) loaded synchronously.
What helps INP:
- Yield to the event loop. Break long tasks with
await scheduler.yield()(Chromium 117+) orawait new Promise((r) => setTimeout(r, 0))for older engines. - Defer non-critical handler work. Wrap analytics in
requestIdleCallback. - Preload event handlers lazily, after first interaction.
- Avoid forced synchronous layout — read DOM measurements before writing.
Per the Chrome Web Vitals 2024 report, about 60% of INP regressions trace to a single third-party script.
CLS: layout stability
CLS aggregates every unexpected layout shift in the page’s lifecycle. Each shift’s impact is the area of moved content times the distance moved, summed and weighted by viewport.
What causes CLS:
- Images and ads that load late and push content down. Always
set
widthandheight(oraspect-ratio). - Web fonts that swap, causing reflow. Use
font-display: swapwith a size-adjusted fallback. - Dynamically inserted banners (cookie consent, signup CTAs).
Reserve space; do not animate from
block-size: 0. - DOM injections above existing content.
About 70% of CLS regressions are attributable to images without explicit dimensions, per the State of CSS 2023 perf section.
Field vs lab measurement
Two ways to track the metrics:
- Field data — real user measurements via the
web-vitalsJavaScript library or CrUX. Google ranks pages on field data. - Lab data — synthetic measurements via Lighthouse, WebPageTest, PageSpeed Insights. Useful for CI and pre-launch checks; not ranked by search.
Field and lab usually agree on direction but disagree on magnitude. Lab tools cannot replicate real-network jitter, real-CPU heterogeneity, or real-user interaction patterns. Always confirm field-data wins after a deploy.
Cross-engine support
Each vital has a measurement primitive:
- LCP — PerformanceObserver +
largest-contentful-paintentries; cross-engine 2020 across Chromium, WebKit (15+), Gecko (122+, 2024). - INP — PerformanceObserver +
evententries plusinteractionId; cross-engine 2024. - CLS — PerformanceObserver +
layout-shiftentries; cross-engine 2022.
The Web Vitals JS library handles cross-engine differences and exposes a uniform API.
Further reading
- web.dev Core Web Vitals overview.
web-vitalslibrary on GitHub with examples for each metric.- Annie Sullivan’s INP migration write-up is the canonical reference for the FID-to-INP transition.
- HTTP Archive 2024 CWV report for adoption data.