Web Performance

Core Web Vitals: Complete Guide 2026

Core Web Vitals diagram: LCP, INP, CLS

LCP, INP and CLS — three Google metrics that directly affect rankings. How to measure, diagnose and improve each one.

Core Web Vitals (CWV) are Google's set of metrics measuring real user experience: loading speed, interface responsiveness and visual stability. Since May 2021 they are part of Page Experience and factor into ranking.

All three metrics are evaluated per URL — great scores on your homepage won't help product pages. Google sources data from Chrome UX Report (real users), not lab simulations.

Google evaluates CWV at the p75 threshold — the 75th percentile. A page is "good" when 75% of real users experience the metric in the green zone. Lab tools like Lighthouse show a median device — useful for diagnosis, not final assessment.

What are Core Web Vitals

≤ 2.5 s

LCP — good

Largest element rendered

≤ 200 ms

INP — good

Interface responded to input

≤ 0.1

CLS — good

Minimal layout shift

75%

Assessment threshold

Share of users in the green zone

History: from FID to INP

Google introduced Core Web Vitals in 2020 with three metrics: LCP, FID (First Input Delay) and CLS. FID measured the delay of the first tap — valuable, but covering only a fraction of page interactivity.

May 2020Core Web Vitals announced

Google introduces three metrics: LCP, FID, CLS. Tools begin supporting the new signals.

June 2021Page Experience Update

CWV officially enter the ranking algorithm. Rollout completes in August 2021.

March 2024FID → INP

Interaction to Next Paint replaces First Input Delay. INP covers all interactions during the session, not just the first.

2025–2026INP in the wild

Sites with heavy JS (SPAs, e-commerce, filters) feel INP pressure. Long Task optimisation becomes a priority.

LCP — Largest Contentful Paint

LCP records the moment the largest visible contentful block on the page is fully painted. Typically this is a hero image, article cover or a large H1 heading.

LCP valueRatingAction
≤ 2.5 sGoodMaintain, monitor in GSC
2.5 – 4.0 sNeeds improvementOptimise images, reduce TTFB
> 4.0 sPoorCritical priority, audit immediately

Common causes of slow LCP

  • Slow TTFB (server, CDN, no caching) — accounts for up to 40% of LCP time
  • Hero image not prioritised: missing fetchpriority="high"
  • Hero image not preloaded (<link rel="preload">)
  • Render-blocking CSS/JS delays first paint
  • Images too large: no WebP/AVIF, no srcset
  • LCP element behind JS render (React SSR not complete at LCP time)
HTML
<!-- Prioritise the LCP image -->
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high" />

<img
  src="/hero.webp"
  alt="Hero"
  fetchpriority="high"
  loading="eager"
  decoding="async"
  width="1280"
  height="720"
/>
Don't use loading="lazy" on hero images — the browser will defer loading them and LCP will increase. Use lazy only for images below the fold.

INP — Interaction to Next Paint

INP measures the delay from any user interaction (click, keypress, tap) to the next visual paint of the page. Unlike FID, INP tracks all interactions during the session and uses the worst case (with outlier trimming).

INP anatomy

INP = input delay + processing time + presentation delay

Input delay (queue wait)up to 50 ms
Processing time (JS handler)up to 100 ms
Presentation delay (render + paint)up to 50 ms

What breaks INP

  • Long Tasks > 50 ms block the main thread — browser can't handle input
  • Heavy event handlers: synchronous setState in React, mass DOM updates
  • No scheduler.yield() or setTimeout(0) to break up long tasks
  • Third-party scripts (chat, ads, analytics) occupy the main thread
  • JS-driven animations instead of CSS transform/opacity
JAVASCRIPT
// Breaking up a Long Task with scheduler.yield()
async function processLargeList(items) {
  for (let i = 0; i < items.length; i++) {
    processItem(items[i]);
    // Yield to the main thread every 50 items
    if (i % 50 === 0) {
      await scheduler.yield();
    }
  }
}
scheduler.yield() is a modern alternative to setTimeout(0). The browser returns control, processes user input, then resumes the task. Supported in Chrome 115+; polyfill with setTimeout for others.

CLS — Cumulative Layout Shift

CLS is a unitless metric describing the total unexpected shift of page elements. Formula: impact fraction × distance fraction. Shifting a pressed button doesn't count — only elements that shift without user action.

CLS valueRatingTypical cause
≤ 0.1GoodSpace reserved for all elements
0.1 – 0.25Needs improvementFonts without font-display: swap, banners
> 0.25PoorImages without dimensions, dynamic inserts

Common CLS sources

  • Images without width and height attributes — browser doesn't know the size before load
  • Web fonts without font-display: optional or swap — FOUT shifts text
  • Dynamically injected banners, cookie notices at the top of the page
  • CSS animations changing top/left/margin instead of transform
  • Ads without reserved space (min-height on container)
CSS
/* Reserve space for an ad slot */
.ad-container {
  min-height: 250px;
  width: 100%;
}

/* Animation without CLS: transform and opacity only */
.card:hover {
  transform: translateY(-4px);
  /* Wrong: margin-top: -4px — this shifts layout */
}

Impact on rankings

Google confirmed: CWV is one of the Page Experience signals that participates in ranking. But it's a tiebreaker, not the primary factor. A page with great content but poor CWV will outrank a page with great CWV but weak content.

Real CWV effect: green-zone sites have lower bounce rates and appear in Google Search Console's Page Experience report. Quick test: if a competitor with similar content outranks you, check their CWV in PageSpeed Insights.

The indirect effect matters more: fast pages reduce bounce rate, increase session depth and conversion. The business case for CWV is stronger than the SEO case. Amazon found: +100 ms to LCP = -1% revenue.

How to measure CWV

There are two data types: lab data (simulation — Lighthouse, WebPageTest) and field data (real users — CrUX, GSC). Google ranks based on field data. Lab is for diagnosis.

TypeToolWhat it showsUse case
FieldGoogle Search ConsoleCWV for all site URLs (p75)Prioritise problematic pages
FieldCrUX Dashboard (Looker)28-day window trendsTrack progress over time
LabPageSpeed InsightsLCP/INP/CLS + recommendationsDiagnose a specific URL
LabLighthouse (DevTools)Detailed waterfall, traceDeep-dive root cause analysis
LabWebPageTestVideo recording, filmstripBefore/after comparison
PageSpeed Insights shows both data types on one page: field data (CrUX) at the top, lab data (Lighthouse) below. Use field data to assess status, lab data to find root causes.

Diagnostic tools

ToolFreeLCPINPCLSField data
Google Search ConsoleYes
PageSpeed InsightsYes✓ (CrUX)
Chrome DevToolsYes
Lighthouse CIYes
WebPageTestYes (limits)
SpeedCurvePaid
Sentry (web-vitals SDK)Freemium
For production monitoring, add Google's web-vitals JS library — it collects real CWV and sends them to your analytics platform (GA4, Sentry, DataDog).
JAVASCRIPT
// web-vitals v4 — collect real CWV
import { onLCP, onINP, onCLS } from 'web-vitals';

function sendToAnalytics({ name, value, id }) {
  // Send to GA4
  gtag('event', name, {
    value: Math.round(name === 'CLS' ? value * 1000 : value),
    metric_id: id,
    metric_delta: value,
  });
}

onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);

Optimization checklist

LCP

  • Add fetchpriority="high" and remove loading="lazy" from the hero image
  • Add <link rel="preload" as="image"> for hero in <head>
  • Convert images to WebP or AVIF, configure srcset
  • Reduce TTFB to ≤ 800 ms: CDN, caching, Edge SSR
  • Remove render-blocking scripts from <head> (async/defer/module)
  • Set Cache-Control: max-age=31536000 for static assets

INP

  • Profile Long Tasks in Chrome DevTools → Performance → Main Thread
  • Break tasks > 50 ms with scheduler.yield() or setTimeout(0)
  • Debounce input / scroll handlers (16–100 ms)
  • Optimise React: useMemo, useCallback, React.memo, list virtualisation
  • Move third-party scripts to Web Workers or load after LCP
  • CSS animations via transform and opacity only

CLS

  • Set width and height on all <img> elements — browser reserves space
  • Use aspect-ratio for containers with unknown dimensions
  • Configure font-display: optional for critical fonts
  • Reserve min-height for ad slots and dynamic content
  • Place notices (cookie, banners) at the bottom, not top of the page
  • Check FOUT: fonts without a fallback shift text on load
Priority order: start with LCP — it's most often red and carries the most weight in Page Experience. Once LCP is green, move to INP (critical for SPAs and interactive pages), then CLS.
Core Web Vitals are three Google metrics — LCP, INP, and CLS — measuring load speed, interactivity, and visual stability. Since May 2021 they are part of the Page Experience Signal and directly affect rankings: poor scores suppress positions, good scores give a small boost all else being equal.
Use Google Search Console (Core Web Vitals report), PageSpeed Insights (real-world CrUX data + lab data), Chrome DevTools Performance tab, or Lighthouse. For continuous monitoring integrate the web-vitals.js library and send data to GA4.
Very urgent. Anything above 4 s falls into 'Poor' and Google will demote the page. Start with diagnosis: the culprit is usually an unoptimised hero image, slow server TTFB, or render-blocking scripts. Dropping LCP to under 2.5 s typically produces measurable ranking gains within 2–4 weeks of re-crawl.
The thresholds are the same (LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1) but scores are measured separately. Mobile almost always performs worse due to slower CPUs and networks. GSC shows both segments — prioritise mobile.
Yandex does not use CWV as a direct ranking signal, but page speed is factored in through Yandex.Metrica's own metrics. Good CWV indirectly improve behavioural signals — bounce rate, scroll depth — which Yandex weighs more heavily than Google does.
Roughly every few years when the web landscape shifts significantly. INP replaced FID in 2023; its threshold was adjusted in 2024. Google announces changes on web.dev/blog and Google Search Central 6–12 months in advance.
LCP is more critical for conversions: a slow main element on a product or landing page directly reduces sales (roughly −1% conversion per +0.1 s LCP per Google data). CLS is more critical for UX: a Buy button shifting under the cursor is a direct source of drop-offs. Work on both in parallel.