Core Web Vitals: Measure and Improve for Better Web Performance
Your website loads, but users still bounce. Slow interactions frustrate visitors, and search engines notice. Core Web Vitals are Google's metrics for real-world user experience: Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). In this guide, we'll show you how to measure them accurately and improve them with practical, code-level techniques.
What Are Core Web Vitals?
Core Web Vitals are a set of metrics that quantify key aspects of user experience:
- LCP measures loading performance. It marks the time when the largest content element (image, text block, video) becomes visible. Aim for ≤ 2.5 seconds.
- INP measures interactivity. It tracks the latency of all interactions (clicks, taps, key presses) and reports the worst one. Aim for ≤ 200 milliseconds.
- CLS measures visual stability. It scores unexpected layout shifts during loading. Aim for ≤ 0.1.
These metrics are part of Google's Page Experience signal, but more importantly, they reflect real user frustration. Improving them benefits both SEO and conversion rates.
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 CI) provides a snapshot with opportunities to improve.
- PageSpeed Insights combines lab and field data from the Chrome User Experience Report (CrUX).
- WebPageTest offers advanced scripting and filmstrip views.
Field Tools
- Chrome UX Report (CrUX) shows aggregated real-user data for your origin.
- web-vitals library lets you collect metrics from actual users and send them to your analytics.
- Search Console reports Core Web Vitals status for your site.
Start by checking PageSpeed Insights for your key pages. Then set up real-user monitoring with the web-vitals library to track performance over time.
Improving LCP
LCP is often the most impactful metric to fix. The largest element is usually a hero image or a large text block.
1. Optimize the Critical Path
- Reduce server response time (TTFB) with caching, CDNs, and efficient backend code.
- Eliminate render-blocking resources: inline critical CSS, defer non-critical CSS and JavaScript.
- Preload the LCP image:
<link rel="preload" as="image" href="#">.
2. Optimize Images
- Use modern formats like WebP or AVIF.
- Serve responsive images with
srcsetandsizes. - Compress images without visible quality loss. For quick compression, try our Image Compressor.
3. Improve Server Response
- Use a CDN to cache static assets globally.
- Enable Brotli or gzip compression.
- Optimize database queries and use server-side caching.
Example: preload and fetchpriority for LCP image:
<link rel="preload" as="image" href="#" fetchpriority="high">
<img src="#" alt="Hero" width="1200" height="600" fetchpriority="high">
Improving INP
INP measures how quickly your page responds to user input. High INP means sluggish interactions.
1. Break Up Long Tasks
- Use
setTimeout,requestIdleCallback, orscheduler.yieldto yield to the main thread. - Avoid long-running JavaScript functions; split them into smaller chunks.
2. Optimize Event Handlers
- Debounce or throttle frequent events (scroll, resize, input).
- Use passive event listeners for touch and wheel events.
- Minimize DOM updates inside handlers.
3. Reduce JavaScript Execution
- Code-split and lazy-load non-critical JavaScript.
- Remove unused dependencies and polyfills.
- Use web workers for heavy computations.
Example: yield to main thread in a long task:
async function processLargeArray(items) {
for (let i = 0; i < items.length; i++) {
// Process item
if (i % 50 === 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
}
}
Improving CLS
CLS measures unexpected layout shifts. Common causes: images without dimensions, ads, embeds, and dynamically injected content.
1. Always Set Dimensions
- Include
widthandheightattributes on images and videos. - Use CSS
aspect-ratiofor responsive containers.
2. Reserve Space for Dynamic Content
- Use placeholders or skeleton screens for ads and embeds.
- Avoid inserting content above existing content unless in response to user interaction.
3. Optimize Font Loading
- Use
font-display: swapto avoid invisible text, but be aware of potential layout shifts. - Preload key fonts to reduce swap delays.
Example: reserve space with aspect-ratio:
.video-container {
aspect-ratio: 16 / 9;
width: 100%;
}
Tools and Workflow
Integrate performance checks into your development workflow:
- Run Lighthouse in CI (e.g., GitHub Actions) to catch regressions.
- Use the web-vitals library to send field data to your analytics.
- Monitor CrUX and Search Console for real-user trends.
- Test on real devices, especially mid-range mobile phones.
Remember: performance is a feature. Treat it like any other quality metric.
FAQ
What are the current thresholds for Core Web Vitals?
LCP: good ≤ 2.5s, needs improvement ≤ 4.0s. INP: good ≤ 200ms, needs improvement ≤ 500ms. CLS: good ≤ 0.1, needs improvement ≤ 0.25. These thresholds are based on real-user data.
How often should I measure Core Web Vitals?
Monitor field data continuously through tools like CrUX and your own RUM. Run lab tests on every significant code change and at least monthly for key pages.
Can I improve Core Web Vitals without a developer?
Some fixes like image compression and caching can be done via plugins or CDN settings. However, deeper optimizations (code splitting, critical CSS) usually require developer involvement.
Ready to optimize your images for better LCP? Try our free Image Compressor to reduce file sizes without losing quality.