Core Web Vitals are three specific page experience metrics — LCP, CLS, and INP — that Google uses to measure whether a page feels fast, stable, and responsive to real users. They are Google-confirmed ranking signals, and poor scores directly correlate with higher bounce rates, lower conversion rates, and suppressed positions in search results.
This guide explains exactly what each metric measures, what threshold separates a "good" score from a poor one, how to diagnose problems with free tools, and the highest-impact fixes for each.
What Does Each Core Web Vital Actually Measure?
The three metrics each target a distinct aspect of page experience. Here is a full reference table:
| Metric | What It Measures | Good Threshold | How to Diagnose |
|---|---|---|---|
| LCP | Time for the largest above-the-fold element to render | ≤ 2.5 s | PageSpeed Insights, Search Console CWV report |
| CLS | Amount of unexpected layout shift during page load | ≤ 0.1 | Chrome DevTools Layout Shift regions, CrUX |
| INP | Latency from user interaction to next visual update | ≤ 200 ms | Chrome DevTools Performance panel, web-vitals.js |
What Is LCP (Largest Contentful Paint)?
LCP measures the time from when a user starts navigating to a page to when the browser renders the largest image or block of text in the visible viewport. It is the closest proxy Google has to "how fast did this page feel like it loaded?"
The LCP element is almost always one of the following: a hero image or background image loaded via CSS, an <img> tag, a video poster frame, or a large heading. The browser continuously updates which element qualifies as the LCP candidate until the user interacts with the page.
Common causes of poor LCP
- Slow server response time (TTFB): If the server takes over 600 ms to respond, LCP has almost no chance of hitting 2.5 s regardless of frontend optimisation.
- Render-blocking resources: Synchronous CSS and JavaScript in
<head>that must be parsed before the browser can paint anything. - Unoptimised LCP image: A hero image that is not compressed, not served in a modern format (WebP/AVIF), or not preloaded.
- Lazy-loading the LCP image: Adding
loading="lazy"to the above-the-fold hero image delays it significantly — the LCP image should never be lazy-loaded. - Large layout trees: Excessive DOM size slows rendering across all metrics.
How to fix LCP
- Add
<link rel="preload" as="image">for the LCP image in<head>. - Serve images in WebP or AVIF format and set explicit width and height attributes.
- Enable HTTP/2 or HTTP/3 and a CDN with an edge node close to your users.
- Defer non-critical JavaScript and move CSS to be non-render-blocking where possible.
- Use server-side rendering or static site generation to reduce TTFB for content-heavy pages.
What Is CLS (Cumulative Layout Shift)?
CLS measures the sum of all unexpected layout shift scores that occur during the entire lifespan of a page. A layout shift occurs whenever a visible element changes position between two rendered frames without being caused by a user interaction (like scrolling or clicking).
The score is calculated as: impact fraction × distance fraction. The impact fraction is the area of the viewport affected by the shift; the distance fraction is the distance the element moves as a proportion of the viewport. These are summed across all shifts in a "session window" — with Google grouping shifts within 1 second of each other.
Common causes of poor CLS
- Images and iframes without explicit dimensions: When the browser does not know an image's size until it loads, surrounding content jumps downward.
- Late-loading ad slots: Ads that inject above existing content after the page has painted.
- Web fonts causing FOUT/FOIT: When fallback fonts are sized differently from the loaded webfont, text reflows mid-render.
- Dynamically injected content: Banners, cookie notices, or personalisation blocks inserted above existing content without reserved space.
How to fix CLS
- Always include
widthandheightattributes on all<img>and<video>elements so the browser reserves space. - Use CSS
aspect-ratiofor responsive embeds and containers. - Add
font-display: optionalorfont-display: swapwithsize-adjustto reduce font-related shifts. - Pre-reserve space for ad slots and inject dynamic content below the fold or into pre-sized containers.
What Is INP (Interaction to Next Paint)?
INP replaced FID (First Input Delay) as a Core Web Vital in March 2024. While FID only measured the delay before the browser first responded to a user's very first interaction on the page, INP observes the latency of all click, tap, and keyboard interactions throughout the full page session — and reports the worst-case interaction (or near-worst, excluding outliers).
Specifically, INP measures the time from when an interaction begins to when the browser completes painting the next frame in response. This makes it a much more complete picture of whether a page feels sluggish during real use, not just on initial load.
Common causes of poor INP
- Long JavaScript tasks on the main thread: Any script task over 50 ms blocks the browser from responding to interactions. Long tasks are the single biggest driver of poor INP.
- Heavy event handlers: Click or input listeners that trigger synchronous DOM reads and writes, triggering forced layout recalculation.
- Third-party scripts: Analytics, chat widgets, and ad scripts that run continuously on the main thread even after page load.
- Large React or framework hydration: Single-page applications often block the main thread during hydration, making the page unresponsive immediately after load.
How to fix INP
- Break up long JavaScript tasks using
setTimeout(fn, 0),scheduler.yield(), or moving work to a Web Worker. - Debounce or throttle input handlers and avoid triggering synchronous layout inside event listeners.
- Audit and defer or remove third-party scripts that are not critical to the initial page interaction.
- For React/Next.js applications, use concurrent features and Suspense to spread rendering work, and consider server components to reduce client-side JavaScript.
- Use the Chrome DevTools Performance panel to identify the specific interactions with high latency and trace back to the offending script.
How to Measure Core Web Vitals: Field Data vs. Lab Data
One important distinction: Core Web Vitals can be measured in two ways. Lab data (from Lighthouse or PageSpeed Insights) simulates a page load in a controlled environment. Field data (from the Chrome User Experience Report, or CrUX) reflects actual Chrome user experiences aggregated over the past 28 days. Google Search Console and PageSpeed Insights both show CrUX field data where available.
Google uses field data for ranking purposes, not lab data. Your Lighthouse score might look great while your CrUX field data is poor, particularly for INP — which requires real user interactions to measure. Always diagnose with field data first, then use lab tools to reproduce and fix the problem.
Quick audit checklist: Open Google Search Console → Core Web Vitals → click "Open Report" for mobile. Fix the URLs flagged as Poor first, then Needs Improvement. Prioritise your highest-traffic templates (homepage, category pages, product pages) before individual URLs.