Core Web Vitals: Measure and Improve Web Performance
Your users expect pages to load instantly, respond without delay, and stay visually stable. Google's Core Web Vitals (CWV) quantify these expectations: Largest Contentful Paint (LCP) measures loading, Interaction to Next Paint (INP) measures interactivity, and Cumulative Layout Shift (CLS) measures visual stability. Poor CWV scores hurt user experience and can affect search rankings. This guide shows you how to measure each metric and improve them with practical, developer-friendly steps.
What Are Core Web Vitals?
Core Web Vitals are three metrics that reflect real-world user experience:
- LCP: Time until the largest content element (image, text block, video) is rendered. Good: ≤2.5s, Needs improvement: ≤4s, Poor: >4s.
- INP: Time from user interaction (click, tap, keypress) to the next frame painted. Good: ≤200ms, Needs improvement: ≤500ms, Poor: >500ms.
- CLS: Sum of layout shift scores for unexpected visual movement. Good: ≤0.1, Needs improvement: ≤0.25, Poor: >0.25.
These thresholds are based on the 75th percentile of page loads, segmented across mobile and desktop.
How to Measure Core Web Vitals
You need both lab and field data. Lab tools simulate conditions; field data comes from real users.
Lab Tools
- Lighthouse (in Chrome DevTools or PageSpeed Insights): audits LCP, CLS, and total blocking time (a proxy for INP).
- WebPageTest: advanced filmstrip and waterfall analysis.
- Chrome DevTools Performance panel: record interactions to spot long tasks affecting INP.
Field Tools
- Chrome UX Report (CrUX): aggregated real-user data for public sites.
- web-vitals JavaScript library: send metrics to your analytics.
- Search Console Core Web Vitals report: groups URLs by status.
Install the web-vitals library via npm or include it from a CDN, then log metrics:
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);
Use sendBeacon to avoid blocking unload. Collect data over time to see trends.
Improving Largest Contentful Paint (LCP)
LCP is often the hero image or main heading. Optimize the critical path:
- Prioritize the LCP resource: add
fetchpriority="high"to the LCP image or preload it. - Reduce server response time: use caching, CDN, and efficient backend queries.
- Eliminate render-blocking resources: defer non-critical CSS/JS, inline critical CSS.
- Optimize images: compress, use modern formats (WebP/AVIF), and set dimensions.
- Use a CDN to serve assets from locations near users.
Example: preload the LCP image and set fetchpriority:
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high">
<img src="/hero.webp" alt="Hero" width="1200" height="600" fetchpriority="high">
For image compression, try our Image Compressor to reduce file size without visible quality loss.
Improving Interaction to Next Paint (INP)
INP reflects responsiveness. Long JavaScript tasks block the main thread and delay visual feedback.
- Break up long tasks: use
setTimeout,requestIdleCallback, orscheduler.yield()to yield to the browser. - Optimize event handlers: debounce input, avoid heavy work in click handlers.
- Reduce JavaScript: code-split, tree-shake, and defer non-critical scripts.
- Use web workers for CPU-intensive work.
- Avoid large DOM updates: batch DOM changes and use virtualization for long lists.
Measure INP in the field with the web-vitals library and use the Performance panel to identify long tasks during interactions.
Improving Cumulative Layout Shift (CLS)
CLS happens when elements move unexpectedly. Common causes: images without dimensions, ads/embeds without reserved space, and late-loading fonts.
- Always set width and height on images and videos, or use CSS
aspect-ratio. - Reserve space for dynamic content (ads, embeds) with min-height.
- Use
font-display: swapand preload key fonts to avoid invisible text and layout shifts. - Avoid inserting content above existing content unless triggered by user interaction.
Example: set aspect ratio for responsive images:
img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}
Comparison of Core Web Vitals
| Metric | Measures | Good Threshold | Primary Optimization |
|---|---|---|---|
| LCP | Loading performance | ≤2.5s | Optimize images, server, critical CSS |
| INP | Interactivity | ≤200ms | Reduce JS, break long tasks |
| CLS | Visual stability | ≤0.1 | Set dimensions, reserve space |
Practical Workflow to Improve CWV
- Measure baseline: run Lighthouse and collect field data via web-vitals.
- Identify bottlenecks: use Performance panel and network waterfall.
- Prioritize fixes: focus on the metric with the worst score.
- Implement changes: optimize images, defer scripts, set dimensions.
- Test and monitor: re-run lab tests and track field data over time.
Remember that CWV are field metrics; lab tools help diagnose but real-user data is the source of truth.
FAQ
What are the current thresholds for Core Web Vitals?
Good: LCP ≤2.5s, INP ≤200ms, CLS ≤0.1. Needs improvement: LCP ≤4s, INP ≤500ms, CLS ≤0.25. Poor: above those values. These are assessed at the 75th percentile of page loads.
How often should I measure Core Web Vitals?
Monitor field data continuously and run lab audits after major changes. At minimum, review Search Console's Core Web Vitals report monthly and after deployments that affect frontend performance.
Can I improve Core Web Vitals without redesigning my site?
Yes. Many improvements are technical: compress images, set width/height attributes, defer non-critical JavaScript, and break up long tasks. These changes often yield significant gains without visual redesign.
Ready to optimize your images for better LCP? Use our free Image Compressor to shrink images while preserving quality and boost your Core Web Vitals scores.