Core Web Vitals: Measure and Improve Web Performance
You've built a fast website, but users still complain about slowness. Or maybe your SEO rankings dipped after a Google update. The culprit might be Core Web Vitals—Google's metrics for user experience. In this guide, you'll learn what they are, how to measure them, and concrete steps to improve each one.
What Are Core Web Vitals?
Core Web Vitals are three metrics that quantify key aspects of user experience:
- Largest Contentful Paint (LCP): How long it takes for the largest content element (image, video, or text block) to become visible. Good: ≤2.5s.
- Interaction to Next Paint (INP): Measures responsiveness—the time from a user interaction (click, tap, key press) to the next frame painted. Good: ≤200ms.
- Cumulative Layout Shift (CLS): Quantifies unexpected layout shifts during loading. Good: ≤0.1.
These metrics are part of Google's page experience signals and directly impact SEO and user satisfaction.
How to Measure Core Web Vitals
You need both lab and field data. Lab data (synthetic testing) helps debug; field data (real user monitoring) reflects actual experience.
Lab Tools
- Lighthouse in Chrome DevTools: Run audits and get scores with opportunities to improve.
- WebPageTest: Advanced testing with filmstrips and waterfall charts.
- PageSpeed Insights: Combines lab and field data from CrUX.
Field Tools
- Chrome User Experience Report (CrUX): Public dataset of real-user metrics.
- web-vitals JavaScript library: Collect metrics from real users via analytics.
- Search Console: Core Web Vitals report shows URL groups needing attention.
Here's how to use the web-vitals library to send metrics to your analytics:
import {onLCP, onINP, onCLS} from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify(metric);
// Use navigator.sendBeacon if available
(navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) ||
fetch('/analytics', {body, method: 'POST', keepalive: true});
}
onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
Improving LCP
LCP is often the most impactful metric. To improve it:
- Optimize the LCP element: Identify it (usually a hero image or heading) and ensure it loads quickly.
- Preload critical resources: Use
<link rel="preload">for images, fonts, and stylesheets. - Use modern image formats: Serve WebP or AVIF with fallbacks.
- Implement lazy loading carefully: Don't lazy-load the LCP image; prioritize it.
- Reduce server response time: Use CDNs, caching, and optimize backend.
- Eliminate render-blocking resources: Defer non-critical CSS and JavaScript.
Example: preload your hero image:
<link rel="preload" as="image" href="/hero.webp" imagesrcset="/hero-480.webp 480w, /hero-800.webp 800w" imagesizes="(max-width: 600px) 480px, 800px">
Improving INP
INP measures responsiveness. High INP often comes from long tasks blocking the main thread.
- Break up long tasks: Use
setTimeout,requestIdleCallback, orscheduler.yield()to yield to the main thread. - Optimize event handlers: Debounce or throttle expensive operations.
- Reduce JavaScript execution: Code-split, tree-shake, and defer non-critical scripts.
- Avoid large DOM updates: Batch DOM changes and use virtual DOM wisely.
- Use web workers for CPU-intensive work.
Example: yielding with scheduler.yield() (where supported):
async function handleClick() {
// Do some work
await scheduler.yield();
// Continue after yielding
}
Improving CLS
CLS is about visual stability. Prevent unexpected shifts:
- Always include width and height attributes on images and videos.
- Reserve space for ads and embeds with CSS aspect-ratio or fixed dimensions.
- Avoid inserting content above existing content unless triggered by user interaction.
- Use CSS transforms for animations instead of properties that trigger layout.
- Preload fonts and use
font-display: swapto avoid invisible text shifts.
Example: reserve space with aspect-ratio:
.video-container {
aspect-ratio: 16 / 9;
width: 100%;
}
Comparison of Core Web Vitals
| Metric | What it measures | Good threshold | Common fixes |
|---|---|---|---|
| LCP | Loading performance | ≤2.5s | Optimize images, preload, reduce server time |
| INP | Responsiveness | ≤200ms | Break long tasks, optimize JS, use workers |
| CLS | Visual stability | ≤0.1 | Set dimensions, reserve space, avoid dynamic inserts |
Tools and Workflow
Integrate Core Web Vitals monitoring into your development workflow:
- Run Lighthouse in CI to catch regressions.
- Use RUM (Real User Monitoring) to track field data.
- Set performance budgets and alerts.
- Regularly audit third-party scripts—they often impact INP and LCP.
For quick image optimization before uploading to your site, try our Image Compressor to reduce file sizes without quality loss.
FAQ
What are the current thresholds for Core Web Vitals?
LCP good ≤2.5s, needs improvement ≤4s; INP good ≤200ms, needs improvement ≤500ms; CLS good ≤0.1, needs improvement ≤0.25.
How often should I measure Core Web Vitals?
Continuously via field data, and on every significant code change via lab tools. Set up alerts for regressions.
Can I improve Core Web Vitals without rebuilding my site?
Yes—many fixes like image optimization, preloading, and deferring scripts can be applied incrementally.