Core Web Vitals: Measure and Improve Web Performance

Web2026-11-09TryQuickToolBox

You've built a modern web app, but users complain it feels slow. Search rankings might suffer too. Core Web Vitals (CWV) are Google's metrics for user experience: Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). This guide shows you how to measure them accurately and improve them effectively.

What Are Core Web Vitals?

Core Web Vitals are three metrics that quantify key aspects of user experience:

These metrics are field-measured (from real users) and lab-measured (in controlled environments). Both matter.

How to Measure Core Web Vitals

You need both field and lab data to diagnose issues.

Field Data (Real User Monitoring)

Field data reflects actual user experiences across devices and networks. Use these sources:

import {onLCP, onINP, onCLS} from 'web-vitals';

function sendToAnalytics(metric) {
  const body = JSON.stringify(metric);
  navigator.sendBeacon('/analytics', body);
}

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

Lab Data (Synthetic Testing)

Lab tools simulate loading in a controlled environment, making them great for debugging and CI integration.

Best practice: Use lab data to identify fixes, and field data to validate impact.

Improving Largest Contentful Paint (LCP)

LCP is usually dominated by the hero image or a large text block. Optimize these:

  1. Optimize the LCP resource: Compress images (use WebP/AVIF), serve responsive sizes with srcset, and preload the LCP image if it's critical.
  2. Eliminate render-blocking resources: Inline critical CSS, defer non-critical CSS and JavaScript.
  3. Improve server response time (TTFB): Use a CDN, enable caching, and optimize backend queries.
  4. Reduce client-side rendering: For SPAs, consider server-side rendering (SSR) or static generation for the initial view.

Example: Preload the LCP image:

<link rel="preload" as="image" href="/hero.avif" imagesrcset="/hero-480.avif 480w, /hero-800.avif 800w" imagesizes="(max-width: 600px) 480px, 800px">

Improving Interaction to Next Paint (INP)

INP measures the delay between a user interaction and the next paint. Long tasks and heavy JavaScript are common culprits.

  1. Break up long tasks: Use setTimeout, requestIdleCallback, or the scheduler API to yield to the main thread.
  2. Optimize event handlers: Debounce or throttle expensive handlers; avoid layout thrashing.
  3. Reduce JavaScript execution time: Code-split, tree-shake, and defer non-critical scripts.
  4. Use web workers for CPU-intensive work.

Example: Yield to the main thread:

async function yieldToMain() {
  if ('scheduler' in window && 'yield' in scheduler) {
    return scheduler.yield();
  }
  return new Promise(resolve => setTimeout(resolve, 0));
}

async function handleClick() {
  // ... do some work
  await yieldToMain();
  // ... continue
}

Improving Cumulative Layout Shift (CLS)

CLS occurs when elements shift unexpectedly. Prevent it by:

Example: Reserve space for an ad:

<div>
  <!-- ad loads here -->
</div>

Tools and Workflow for Continuous Improvement

Performance is not a one-time fix. Integrate measurement into your workflow:

For a quick check, run your page through PageSpeed Insights; it combines lab and field data.

FAQ

What are the current thresholds for Core Web Vitals?

LCP: good ≤2.5s, needs improvement ≤4s, poor >4s. INP: good ≤200ms, needs improvement ≤500ms, poor >500ms. CLS: good ≤0.1, needs improvement ≤0.25, poor >0.25.

How often is CrUX data updated?

CrUX data is updated daily, but the dataset reflects a rolling 28-day window. Search Console updates periodically.

Can I improve Core Web Vitals without changing my design?

Yes. Many improvements are technical: optimizing images, deferring scripts, reserving space for dynamic content, and reducing main-thread work.

Ready to analyze your site's performance? Use our Nginx log analyzer to identify slow server responses that impact TTFB and LCP.