Articles

Understanding Core Web Vitals (and How to Improve Them)

Core Web Vitals affect both user experience and search ranking. Here's what LCP, INP, and CLS actually measure and the highest-impact ways to fix each one.

Takina Takina · · Updated · 5 min read
Light trails from fast-moving traffic at night

Core Web Vitals are three metrics Google uses to score how a page feels to real users: Largest Contentful Paint (loading — good is 2.5 seconds or less), Interaction to Next Paint (responsiveness — 200 milliseconds or less), and Cumulative Layout Shift (visual stability — 0.1 or less). They feed into search ranking, but their real value is simpler: they’re a measurable proxy for whether visitors stick around. Google’s reference for the program lives at web.dev/articles/vitals.

One detail explains most confusion about scores, so internalize it first: each metric is judged at the 75th percentile of real visits. Your page passes only if three-quarters of visits hit the target — a fast experience on your laptop proves nothing about the phones your audience actually uses.

LCP: how fast the main thing shows up

Largest Contentful Paint measures the time from navigation until the largest visible element — usually the hero image or headline — finishes rendering. It’s the metric closest to a user’s gut sense of “the page has loaded.”

Highest-impact fixes, roughly in order:

  • Speed up the server response. Nothing renders before the first byte arrives. Cache HTML where you can — any caching layer between the user and your origin cuts time to first byte — and serve assets from a CDN so responses come from near the visitor.
  • Prioritize the LCP image. Put it in the initial HTML as a plain <img> — not a CSS background or a client-side render — add fetchpriority="high", and preload it if it’s discovered late:
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high">
  • Never lazy-load the LCP element. loading="lazy" on the hero image is a classic self-inflicted wound.
  • Cut render-blocking CSS and JavaScript, and serve modern formats (AVIF/WebP) at the size actually displayed.

INP: how fast the page reacts

Interaction to Next Paint measures the delay between a user interaction — click, tap, key press — and the next visual update. It replaced First Input Delay in 2024 and is stricter: it considers interactions across the whole visit and reports one of the worst, so a single janky menu can fail the page.

INP is almost always a JavaScript problem. The main thread does one thing at a time, so a long task means the paint after your click has to wait.

  • Break up long tasks. Anything over 50ms of continuous work delays interactions; chunk it and yield back to the browser between pieces.
  • Ship less JavaScript. Framework-heavy pages pay for hydration — re-running component code in the browser before anything responds. Server-render more, hydrate less, and let a bundler like Vite split code by route so users only download what the page needs.
  • Avoid re-render storms. A keystroke that re-renders an entire component tree turns typing into lag. Batch state updates and keep per-interaction work proportional to what actually changed.
  • Move non-urgent work out of handlers. Analytics, logging, and prefetching don’t belong in the click path.

Interactivity doesn’t have to mean heavy scripts — static site search with Pagefind is a good example of adding a rich feature while keeping the main thread quiet.

CLS: does the page hold still

Cumulative Layout Shift measures unexpected movement — content jumping as things load. The formal score multiplies how much of the viewport shifted by how far it moved, but the intuition is enough: this is the tapped-the-wrong-button-because-an-ad-appeared metric.

  • Give images and embeds dimensions. width and height attributes (or CSS aspect-ratio) let the browser reserve space before the file arrives.
  • Reserve space for ads and iframes. Fixed-size slots with a min-height are the single biggest fix on monetized sites — an ad that pops in and shoves the article down is the canonical CLS failure.
  • Handle web fonts. A late font that reflows the page counts too. Preload critical fonts and pair font-display: swap with a fallback font that’s metrically close.
  • Insert new content below the fold or into space you reserved — never push existing content down.

Field data vs. lab data (and why they disagree)

There are two kinds of measurement, and mixing them up wastes debugging time:

Field data (CrUX)Lab data (Lighthouse)
SourceReal Chrome users, 28-day rolling windowOne synthetic load on demand
ConditionsEvery device and network your visitors haveOne simulated device and connection
Includes INPYes — real interactionsNo — lab runs don’t interact
Used for rankingYesNo
Best forKnowing whether you actually passReproducing and fixing problems

A page can ace Lighthouse and still fail Core Web Vitals in the field, because the lab simulates one mid-range profile while your field data includes slow phones on cellular connections. The reverse happens too. Treat field data as the scoreboard and lab data as the debugger.

How to measure yours

PageSpeed Insights is the fastest start: it shows CrUX field data for your URL — when Google has enough traffic to report it — alongside a fresh Lighthouse run with diagnostics. For site-wide coverage, Search Console’s Core Web Vitals report groups similar URLs, which is how you spot patterns: every product page failing CLS points at a template, not one page.

Fix whichever metric sits furthest from its threshold, ship, then wait. Field data is a 28-day window, so improvements take weeks to register fully.

Do Core Web Vitals affect rankings?

Yes — but keep it in proportion. Page experience is a ranking consideration and vitals are how it’s measured, yet content relevance dominates. A thin page will not outrank a genuinely useful one because it loads 400ms faster. The realistic framing: bad vitals can drag you down in competitive results, good vitals remove that drag, and users abandon slow pages regardless of what Google thinks. Optimize for the visitor; the ranking benefit comes along for free.

The takeaway

Core Web Vitals reduce “does this page feel good” to three numbers: LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1, each judged at the 75th percentile of real visits. Prioritize the hero image and server response for LCP, ship less JavaScript in shorter tasks for INP, and reserve space for everything that loads late for CLS. Debug in the lab, but judge yourself on field data — that’s what users experience and what ranking looks at. And remember the ceiling: speed helps, but nothing rescues content people don’t want.

Takina Takina · · 4 min read

What Is the Beacon API? navigator.sendBeacon()

The Beacon API lets a page send one last async request as it unloads, without blocking navigation or racing the browser's page teardown.

#Web Development #Frontend #Performance
Takina Takina · · 4 min read

requestIdleCallback Explained

requestIdleCallback runs low-priority JavaScript when the browser is idle, without blocking rendering, input, or the main thread.

#JavaScript #Performance #Web Development