Mastering Core Web Vitals for SEO in 2024

A technical guide to optimizing LCP, CLS, and INP — the Core Web Vitals metrics Google uses to measure real-world page experience and ranking.

Dashboard showing Core Web Vitals scores in green

Core Web Vitals are Google’s standardized metrics for measuring user experience. Since the Page Experience update, they directly influence search rankings. Getting them right is no longer optional — it’s a baseline requirement for competitive SEO.

The Three Pillars

Largest Contentful Paint (LCP)

LCP measures loading performance: the time from page navigation start until the largest content element in the viewport becomes visible. The target is under 2.5 seconds.

The LCP element is almost always one of:

  • A <img> tag
  • An image inside an <svg> element
  • A <video> poster image
  • An element with a CSS background-image
  • A block-level element containing text

Common LCP bottlenecks and fixes:

<!-- Bad: render-blocking font load delays text LCP -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter">

<!-- Good: preconnect + preload the font display -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter&display=swap">

For image LCP elements, always add fetchpriority="high" and avoid lazy-loading:

<img
  src="/hero.webp"
  alt="Hero image description"
  width="1200"
  height="600"
  fetchpriority="high"
  decoding="async"
/>

Cumulative Layout Shift (CLS)

CLS measures visual stability — how much elements unexpectedly shift during page load. Target is under 0.1.

Always reserve space for images and embeds using aspect-ratio or explicit dimensions:

/* Reserve space before image loads */
.hero-image {
  aspect-ratio: 16 / 9;
  width: 100%;
}

Dynamic content injected above existing content is the #1 cause of high CLS. Use fixed-height containers for ads, cookie banners, and injected elements.

Interaction to Next Paint (INP)

INP replaced First Input Delay (FID) in March 2024. It measures responsiveness: the time from any user interaction (click, tap, key press) to the next visual update. Target is under 200ms.

Key techniques to improve INP:

  1. Break up long JavaScript tasks with scheduler.yield() or setTimeout(0)
  2. Use content-visibility: auto on off-screen sections
  3. Debounce expensive event handlers
  4. Move analytics and third-party scripts to web workers where possible

Measuring Accurately

Field data (real users) beats lab data. Use:

  • Chrome UX Report (CrUX) via PageSpeed Insights for origin-level data
  • Web Vitals JavaScript library for custom RUM
  • Search Console Core Web Vitals report for page-grouped data
import { onLCP, onINP, onCLS } from 'web-vitals';

function sendToAnalytics({ name, value, id }) {
  navigator.sendBeacon('/analytics', JSON.stringify({ name, value, id }));
}

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

Server-Side Wins

No amount of client-side optimization compensates for a slow server. Ensure:

  • TTFB under 600ms — use a CDN, enable HTTP/2, cache aggressively
  • Compression — Brotli over gzip, typically 15–20% smaller
  • Preload critical resources in the <head> before any render-blocking requests

Getting all three Core Web Vitals into the “Good” range typically requires systematic profiling, not guesswork. Start with the CrUX data to find your real-world baseline, then use DevTools Performance panel to trace the specific bottlenecks.