Core Web Vitals are Google’s user-experience metrics. They matter for SEO ranking, but more importantly, they correlate with real user satisfaction. Here’s how to address each one practically.
Largest Contentful Paint (LCP)
LCP measures how quickly the largest visible element renders. Target: under 2.5 seconds.
The biggest LCP killers:
- Slow server response. Use a CDN. If your TTFB is over 800ms, fix the server before anything else.
- Render-blocking resources. Inline critical CSS. Defer non-essential JavaScript.
- Unoptimized images. Use modern formats (WebP/AVIF), proper sizing, and
fetchpriority="high"on the LCP image.
<img
src="/hero.avif"
alt="Hero image"
width="1200"
height="630"
fetchpriority="high"
decoding="async"
/>
The fetchpriority="high" hint tells the browser to prioritize this image in the loading queue. Pair it with a preload for even faster loading:
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high" />
Interaction to Next Paint (INP)
INP replaced FID in March 2024. It measures the latency of all interactions during a page visit, then reports a value near the worst case. Target: under 200ms.
Common INP problems:
- Long tasks on the main thread. Break up JavaScript execution with
scheduler.yield()orsetTimeout. - Expensive re-renders. In React, use
useMemo,useCallback, andReact.memowhere profiling shows they help. - Heavy event handlers. Defer non-visual work. Update the UI first, then do the expensive stuff.
button.addEventListener("click", async () => {
// Update UI immediately
button.textContent = "Processing...";
// Yield to let the browser paint
await scheduler.yield();
// Then do the heavy work
processData();
});
Cumulative Layout Shift (CLS)
CLS measures visual stability — how much elements jump around as the page loads. Target: under 0.1.
The fix is almost always one of these:
- Set explicit dimensions on images and embeds.
- Reserve space for dynamic content (ads, lazy-loaded sections).
- Avoid inserting content above existing content.
- Use
contain-intrinsic-sizefor content-visibility optimizations.
img, video {
max-width: 100%;
height: auto;
aspect-ratio: attr(width) / attr(height);
}
Measuring
Use the Web Vitals library for real-user measurement:
import { onLCP, onINP, onCLS } from "web-vitals";
onLCP(console.log);
onINP(console.log);
onCLS(console.log);
Lab tools like Lighthouse show potential issues. Field data from CrUX or your own RUM tells you what users actually experience. Optimize for field data.