RETURN_TO_BLOG
Updated: AI & SEO 12 min

Core Web Vitals 2026 — How to Improve LCP, INP and CLS

Core Web Vitals are the three metrics Google uses to measure the real user experience on your site: how fast content appears (LCP), how fast the page responds to interactions (INP), and how much the layout "jumps" while loading (CLS). Since March 2024, INP has replaced the older FID, and as of 2025 all three are measurable not just in Chrome but in Firefox and Safari too. This guide explains the exact thresholds, the most common causes of problems, the concrete fixes — and shows how to get strong scores in Next.js without magic and without chasing a perfect "100/100".

Core Web Vitals are the three metrics of real user experience: LCP (how fast content appears), INP (how fast the page responds) and CLS (does the layout jump). I explain the exact thresholds, the common causes and concrete fixes — including Next.js levers — without chasing a perfect Lighthouse 100.

Most performance audits end in the same place: someone opens PageSpeed Insights, sees a red number, panics, and starts optimizing random things. But Core Web Vitals isn't one number to "boost" — it's three separate metrics, each with its own cause and its own cure. Let's start with what they actually mean.

What Core Web Vitals are (and aren't)

Core Web Vitals (CWV) are a subset of Google's broader page experience signals. They measure user experience across three dimensions: loading, interactivity, and visual stability. What sets CWV apart from dozens of other performance metrics is that Google evaluates them using data from real Chrome users — not a single lab measurement.

Key rule: each metric is assessed at the 75th percentile (p75) of page loads over the trailing 28 days. That means at least 75% of visits must meet the "good" threshold for the page to earn a "good" rating. Your fastest test or your own phone doesn't count — what counts is what most real users see, often on slower devices and connections.

The three metrics and their exact thresholds

MetricWhat it measuresGoodNeeds improvementPoor
LCP — Largest Contentful PaintLoading: time until the largest element in the viewport renders≤ 2.5 s2.5–4.0 s> 4.0 s
INP — Interaction to Next PaintResponsiveness: latency of interactions across the page lifecycle≤ 200 ms200–500 ms> 500 ms
CLS — Cumulative Layout ShiftStability: unexpected layout movement (unitless score)≤ 0.10.1–0.25> 0.25

All three thresholds must pass at p75 for the page to pass Core Web Vitals overall. Now, one by one — what breaks them and how to fix them.

LCP — how fast content appears

Largest Contentful Paint measures the time to render the largest element visible in the first screen — usually a hero image, a large heading, or a text block. It's the closest machine proxy for "when does the user see that the page loaded".

Common causes of poor LCP:

  • A slow server and high TTFB (time to first byte).
  • Render-blocking resources — CSS and JavaScript delaying first paint.
  • Large, unoptimized hero images.
  • Lazy-loading the LCP element — a classic mistake: lazy-loading the main image delays its discovery and download.
  • Web fonts blocking text render.

What actually helps:

  • Modern image formats (AVIF/WebP), correct sizing, and `srcset`.
  • The `fetchpriority="high"` attribute on the LCP image — immediately raises its priority.
  • `preload` for late-discovered resources (e.g. an LCP image referenced from CSS).
  • Never lazy-load the LCP image — reserve lazy-loading for off-screen images.
  • Lower TTFB: CDN, caching, faster backend, edge rendering.
  • Fewer render-blocking resources: inline critical CSS, `defer`/`async` non-critical JS.
  • Server-side rendering (SSR/SSG) so HTML with content arrives sooner.

INP — how fast the page responds (the successor to FID)

Interaction to Next Paint is the newest metric. On March 12, 2024, INP officially replaced First Input Delay (FID) as a Core Web Vital. The difference is fundamental: FID measured only the *input delay of the first interaction* — how long before the browser could start handling a click. It ignored how long the processing and rendering actually took.

INP measures far more. It observes all interactions across the whole page lifecycle and reports (roughly) the slowest one, measuring the full time in three phases:

  • Input delay — from the click to the start of event handling.
  • Processing duration — running the event handler callbacks.
  • Presentation delay — time to paint the next frame showing the visual result.

The most common causes of poor INP are long JavaScript tasks blocking the main thread, heavy framework hydration during load, and unoptimized event handlers. What helps:

  • Break up long tasks (over 50 ms) and yield to the main thread (`scheduler.yield()`, `scheduler.postTask()`, yielding via `await`).
  • Less JavaScript: code-splitting and lazy-loading non-critical code.
  • Debounce/throttle high-frequency events.
  • Defer non-urgent UI updates (in React: `useDeferredValue`, `useTransition`).
  • Reduce hydration — fewer client components, partial/progressive hydration.

CLS — does the layout "jump"

Cumulative Layout Shift measures the sum of unexpected layout shifts during loading. It's that irritating moment when you go to click a button and, at the last second, an ad banner pops in and you click something else. It's the only unitless metric.

Causes:

  • Images, video, and `iframe` elements without dimensions.
  • Web fonts (FOUT/FOIT shift on font swap).
  • Dynamically injected content (ads, embeds, banners) inserted above existing content.
  • Late-loading banners and cookie bars.

Fixes:

  • Always set `width`/`height` or CSS `aspect-ratio` on images, video, and iframes.
  • Reserve space for ads, embeds, and dynamically loaded components before they appear.
  • Fonts: a `font-display` strategy plus fallback font metric matching (`size-adjust`) to avoid the swap shift.
  • Don't inject content above already-visible content — insert below or in reserved slots.
  • Animate only `transform` and `opacity` (composited), never `top`/`left`/`width`/`height`.

Field data vs lab data — and the most dangerous myth

This is where most people get lost. There are two completely different kinds of performance data:

  • Field data (RUM): the CrUX dataset (Chrome User Experience Report) — real users, real devices and connections, p75, 28-day window. This is the data Google uses for ranking.
  • Lab data: Lighthouse / PageSpeed Insights in lab mode — a single, simulated load on a fixed device. Great for diagnosis, but not used for ranking.

Hence the industry's most dangerous myth: "100/100 in Lighthouse means good Core Web Vitals". It does not. Analysis of HTTP Archive data shows roughly half of pages scoring 100 in Lighthouse still failed CWV thresholds for real users. A score of 100 only means Lighthouse has nothing more to suggest — not that your users have a good experience.

There's also a hard technical fact: INP cannot be fully measured in the lab at all, because it requires real user interactions. So diagnose in the lab, but judge by field data.

Is Core Web Vitals a ranking factor?

Yes, but smaller than the headlines suggest. CWV are part of the page experience signals (alongside HTTPS, mobile-friendliness, and no intrusive interstitials). Google repeatedly states it will surface the most relevant, helpful content even if its page experience is poor.

The most honest summary: content relevance and quality dominate, and Core Web Vitals act as a tie-breaker — when several pages have comparably valuable content, a better experience can tip the scale. Optimize CWV for the user, for conversions, and for that tie-breaker edge — not as a magic shortcut to the top spot. I cover the bigger picture in SEO vs GEO — Google vs visibility in AI.

How to optimize Core Web Vitals in Next.js

Next.js gives you ready-made levers for each of the three metrics:

  • `next/image` — automatic AVIF/WebP conversion, responsive sizing, and enforced dimensions (protects CLS). Use `priority` on the LCP image (it sets `fetchpriority="high"` and preload) → better LCP. Caution: don't mark multiple images `priority` — competing preloads hurt LCP.
  • `next/font` — self-hosts fonts (no external request) and automatically matches fallback font metrics → eliminates the font-swap shift → better CLS and LCP.
  • SSG / `force-static` (App Router) — prerenders HTML at build time → content delivered faster → better LCP.
  • Server Components — less client JS, less hydration and main-thread work → better INP. The trap: a high-level `"use client"` forces the whole subtree to ship as client code — push the client boundary as low as possible, to the smallest interactive component.

I apply the same approach in practice during a Next.js migration — a fast architectural core is cheaper than patching performance after the fact.

The tools you actually use

  • PageSpeed Insights — shows CrUX field data (top) and Lighthouse lab data (bottom) for a URL or whole origin.
  • Search Console → Core Web Vitals report — based on CrUX, groups URLs by status (Good / Needs improvement / Poor), mobile and desktop separately.
  • The `web-vitals` library — Google's official package to measure LCP/INP/CLS on your own real users (your RUM).
  • Chrome DevTools — since Chrome 132 (January 2025), the Performance panel shows all CWV and CrUX data directly; the old Web Vitals extension was merged into DevTools.

2025–2026: what changed

  • Core Web Vitals went cross-browser. LCP and INP are no longer Chrome-only: Firefox 144 (October 2025) and Safari 26.2 (December 2025) added the APIs needed to measure them.
  • Tooling: the Web Vitals extension was merged into DevTools (Chrome 132); the old CrUX Dashboard was replaced by CrUX Vis (after November 2025).
  • The metrics and thresholds themselves haven't changed since the move to INP in March 2024. Note: if you see claims online about "new 2.0 s LCP thresholds" or "new VSI/ER metrics" — that's misinformation; no such official changes exist. The good LCP threshold is still 2.5 s.

Where to start — order of operations

  • Check field data in Search Console and PSI (not just the Lighthouse score).
  • Identify which of the three metrics is failing — each has a different cure.
  • LCP: optimize the hero image, add `priority`/`fetchpriority`, improve TTFB.
  • INP: trim and break up JavaScript, reduce hydration.
  • CLS: add image dimensions, reserve space for dynamic elements, match fonts.
  • Re-measure after 28 days — CrUX is a rolling average, changes propagate gradually.

---

I do full technical SEO and Core Web Vitals audits — from diagnosing field data to concrete LCP, INP and CLS fixes in code. If you want to learn this from the ground up, I break these topics down in the SEO & GEO course. Get in touch — I'll start with your real CrUX data and show you what delivers the biggest return.

Worth reading next:

/// AUTHOR
Paweł Wiszniewski – AI & Web Engineer

Paweł Wiszniewski

SEO & GEO Specialist & AI Engineer

SEO/GEO specialist (10 years) and AI engineer (3 years). I build search visibility, AI systems and automations that reduce costs and improve operational efficiency.

Signal received?

Terminate
Silence

Initiate protocol. Establish connection. Let's build something loud.

> WAITING_FOR_INPUT...