Core Web Vitals: LCP, INP, CLS Explained & How to Fix Them
· 12 min read
Table of Contents
- What Are Core Web Vitals?
- Why Core Web Vitals Matter for SEO and Business
- Largest Contentful Paint (LCP)
- Interaction to Next Paint (INP)
- Cumulative Layout Shift (CLS)
- How to Measure Core Web Vitals
- Complete Optimization Playbook
- Common Optimization Mistakes to Avoid
- Advanced Optimization Techniques
- Monitoring and Ongoing Maintenance
- Frequently Asked Questions
- Related Articles
Core Web Vitals are Google's official metrics for measuring user experience on the web. Since becoming a ranking factor in June 2021, they've fundamentally transformed how developers, SEOs, and site owners approach page performance. This comprehensive guide breaks down each metric, explains what causes poor scores, and provides concrete, actionable fixes you can implement immediately.
Whether you're optimizing an e-commerce site, a content platform, or a SaaS application, understanding and improving Core Web Vitals is no longer optional—it's essential for both search visibility and user satisfaction.
What Are Core Web Vitals?
Core Web Vitals (CWV) are a set of three specific metrics that Google considers essential for delivering a good user experience. They measure three critical dimensions of page performance that directly impact how users perceive and interact with your website.
The three Core Web Vitals are:
- Largest Contentful Paint (LCP) — Measures loading performance by tracking when the largest visible content element renders
- Interaction to Next Paint (INP) — Measures interactivity by assessing how quickly the page responds to all user interactions
- Cumulative Layout Shift (CLS) — Measures visual stability by quantifying unexpected layout shifts during page load
Unlike synthetic lab tests that run in controlled environments, Google evaluates Core Web Vitals using real-world data from actual Chrome users through the Chrome User Experience Report (CrUX). This means your site needs to perform well for real users on real devices with varying network conditions—not just in your development environment.
Pro tip: Google requires that 75% of page visits meet the "good" threshold for each metric. A single perfect test score isn't enough—you need consistent performance across your entire user base.
The Evolution of Core Web Vitals
Core Web Vitals aren't static. Google originally included First Input Delay (FID) as the interactivity metric, but replaced it with Interaction to Next Paint (INP) in March 2024. This change reflects Google's commitment to measuring what actually matters to users, not just what's easy to measure.
The shift from FID to INP was significant because FID only measured the first interaction, while INP evaluates all interactions throughout the page lifecycle. This provides a more comprehensive view of responsiveness and better correlates with user frustration.
Why Core Web Vitals Matter for SEO and Business
Core Web Vitals are part of Google's page experience signals, which also include mobile-friendliness, HTTPS security, and the absence of intrusive interstitials. While content relevance and authority still dominate rankings, CWV act as a tiebreaker—when two pages are equally relevant, the one with better performance wins.
But the impact extends far beyond search rankings. Performance directly affects your bottom line:
| Metric Improvement | Business Impact | Source |
|---|---|---|
| Pass all CWV thresholds | 24% fewer page abandonments | Google/SOASTA Research |
| 100ms LCP improvement | 1.7% conversion rate increase | Deloitte Digital |
| 0.1 CLS improvement | 3.2% reduction in bounce rate | Akamai Study |
| 200ms INP improvement | 5.8% increase in engagement | Chrome User Experience Report |
Real-world case studies demonstrate these impacts. When Vodafone improved their LCP by 31%, they saw an 8% increase in sales. When Yahoo Japan reduced CLS by 0.2, their session duration increased by 15%. These aren't marginal gains—they're business-transforming improvements.
The Mobile-First Reality
With Google's mobile-first indexing, your mobile Core Web Vitals scores are what matter most. Mobile devices typically have slower processors, less memory, and more variable network conditions than desktop computers, making optimization more challenging but also more critical.
Mobile users are also less forgiving. A study by Google found that 53% of mobile users abandon sites that take longer than 3 seconds to load. Poor Core Web Vitals directly contribute to these abandonment rates.
Largest Contentful Paint (LCP)
Largest Contentful Paint measures how long it takes for the largest visible content element to render in the viewport. This is typically a hero image, video thumbnail, large text block, or background image. LCP is the most intuitive Core Web Vital because it directly correlates with the user's perception of "when did this page load?"
LCP Thresholds
| Rating | LCP Time | User Experience |
|---|---|---|
| Good | ≤ 2.5 seconds | Fast, responsive, professional |
| Needs Improvement | 2.5 - 4.0 seconds | Acceptable but noticeable delay |
| Poor | > 4.0 seconds | Frustrating, likely to abandon |
What Elements Count as LCP?
Not every element on your page is eligible to be the LCP element. Only these element types are considered:
<img>elements<image>elements inside<svg><video>elements with poster images- Elements with background images loaded via CSS
url() - Block-level elements containing text nodes
The LCP element can change as the page loads. Initially, it might be a text heading, but once your hero image loads, that becomes the new LCP element. The final LCP is recorded when the user starts interacting with the page or navigates away.
Common LCP Problems and Solutions
Problem 1: Slow Server Response Times
If your Time to First Byte (TTFB) is slow, everything else suffers. The browser can't start rendering until it receives the HTML document.
Solutions:
- Use a Content Delivery Network (CDN) to serve content from locations closer to users
- Implement server-side caching with Redis or Memcached
- Optimize database queries and add appropriate indexes
- Use HTTP/2 or HTTP/3 for multiplexing and header compression
- Consider edge computing solutions like Cloudflare Workers or Vercel Edge Functions
Problem 2: Render-Blocking Resources
CSS and JavaScript files in the <head> block rendering until they're downloaded and processed.
Solutions:
- Inline critical CSS directly in the HTML for above-the-fold content
- Defer non-critical CSS using
media="print" onload="this.media='all'" - Add
asyncordeferattributes to script tags - Remove unused CSS and JavaScript with tools like PurgeCSS
- Split large bundles into smaller chunks with code splitting
Quick tip: Use our Page Speed Analyzer to identify render-blocking resources and get specific recommendations for your site.
Problem 3: Large Image Files
Unoptimized images are the most common LCP culprit. A 5MB hero image will destroy your LCP score.
Solutions:
- Compress images using modern formats like WebP or AVIF (70-90% smaller than JPEG)
- Implement responsive images with
srcsetandsizesattributes - Use image CDNs that automatically optimize and resize images
- Add
fetchpriority="high"to your LCP image to prioritize its download - Preload LCP images with
<link rel="preload" as="image">
Problem 4: Client-Side Rendering
If your LCP element is rendered by JavaScript, users must wait for the JS to download, parse, and execute before seeing content.
Solutions:
- Use Server-Side Rendering (SSR) or Static Site Generation (SSG)
- Implement streaming SSR with React Server Components or similar technologies
- Use progressive enhancement—render a basic version server-side, enhance with JavaScript
- Consider partial hydration to reduce JavaScript execution time
Advanced LCP Optimization
For sites already meeting the 2.5-second threshold, these advanced techniques can push you into the top performance tier:
Resource Hints: Use <link rel="preconnect"> for critical third-party origins to establish connections early. Use <link rel="dns-prefetch"> for less critical origins.
Priority Hints: The fetchpriority attribute tells the browser which resources matter most. Set fetchpriority="high" on your LCP image and fetchpriority="low" on below-the-fold images.
103 Early Hints: This HTTP status code allows servers to send preload hints before the main response is ready, giving the browser a head start on downloading critical resources.
Interaction to Next Paint (INP)
Interaction to Next Paint measures the responsiveness of your page to user interactions throughout the entire page lifecycle. Unlike its predecessor FID, which only measured the first interaction, INP evaluates every click, tap, and keyboard press to provide a comprehensive view of interactivity.
INP measures the time from when a user initiates an interaction until the browser paints the next frame showing the visual result of that interaction. This includes input delay, processing time, and presentation delay.
INP Thresholds
| Rating | INP Time | User Experience |
|---|---|---|
| Good | ≤ 200 milliseconds | Instant, responsive feedback |
| Needs Improvement | 200 - 500 milliseconds | Noticeable but tolerable lag |
| Poor | > 500 milliseconds | Sluggish, unresponsive, broken |
Understanding INP Components
INP consists of three phases:
- Input Delay: Time from user action to when event handlers start running (main thread must be available)
- Processing Time: Time spent executing event handlers and related JavaScript
- Presentation Delay: Time from handler completion to when the browser paints the next frame
The slowest interaction during a page visit determines your INP score. For pages with many interactions, INP uses the 98th percentile to account for outliers.
Common INP Problems and Solutions
Problem 1: Long Tasks Blocking the Main Thread
JavaScript execution blocks the main thread, preventing the browser from responding to user input. Tasks longer than 50ms are considered "long tasks."
Solutions:
- Break up long tasks using
setTimeout()orrequestIdleCallback() - Use Web Workers to move heavy computation off the main thread
- Implement code splitting to reduce initial JavaScript bundle size
- Defer non-essential JavaScript with
asyncordeferattributes - Use the
isInputPending()API to yield to user input during long tasks
Pro tip: Chrome DevTools Performance panel shows long tasks in red. Record a trace while interacting with your page to identify problematic tasks.
Problem 2: Heavy Event Handlers
Event handlers that perform expensive operations directly in response to user input cause poor INP.
Solutions:
- Debounce or throttle event handlers for scroll, resize, and input events
- Use
requestAnimationFrame()for visual updates - Implement virtual scrolling for long lists instead of rendering all items
- Cache expensive calculations and reuse results when possible
- Use event delegation instead of attaching handlers to many elements
Problem 3: Forced Synchronous Layouts
Reading layout properties (like offsetHeight) after modifying the DOM forces the browser to recalculate layout synchronously, blocking the main thread.
Solutions:
- Batch DOM reads together, then batch DOM writes together
- Use
requestAnimationFrame()to schedule layout-triggering operations - Cache layout measurements when possible
- Use CSS transforms and opacity for animations (they don't trigger layout)
- Consider using the
content-visibilityCSS property to skip layout for off-screen content
Problem 4: Third-Party Scripts
Analytics, ads, chat widgets, and other third-party scripts often execute on the main thread and compete with your code for resources.
Solutions:
- Load third-party scripts asynchronously with
asyncattribute - Use a tag manager to control when and how third-party scripts load
- Implement a facade pattern for heavy widgets (load on user interaction)
- Use
requestIdleCallback()to defer non-critical third-party code - Regularly audit and remove unused third-party scripts
Advanced INP Optimization
Scheduler API: The experimental Scheduler API provides fine-grained control over task prioritization. Use scheduler.postTask() with priority levels to ensure user-facing tasks run first.
React Concurrent Features: If using React, leverage startTransition() to mark non-urgent updates, allowing React to keep the UI responsive during heavy updates.
Interaction Tracking: Implement custom analytics to track which interactions are slowest on your site. Use the PerformanceObserver API to measure event timing in production.
Cumulative Layout Shift (CLS)
Cumulative Layout Shift measures visual stability by quantifying how much visible content shifts unexpectedly during the page lifecycle. We've all experienced this frustration: you're about to click a button when an ad loads above it, shifting everything down and causing you to click the wrong thing.
CLS is calculated by multiplying the impact fraction (how much of the viewport was affected) by the distance fraction (how far elements moved). The score is unitless, with lower being better.
CLS Thresholds
| Rating | CLS Score | User Experience |
|---|---|---|
| Good | ≤ 0.1 | Stable, predictable layout |
| Needs Improvement | 0.1 - 0.25 | Occasional unexpected shifts |
| Poor | > 0.25 | Frequent, jarring layout changes |
Common CLS Problems and Solutions
Problem 1: Images Without Dimensions
When images load without explicit width and height attributes, the browser doesn't know how much space to reserve, causing content to shift when the image finally loads.
Solutions:
- Always include
widthandheightattributes on<img>tags - Use the
aspect-ratioCSS property for responsive images - Set
min-heighton image containers to reserve space - Use the
object-fitCSS property to control how images fill their containers - Implement skeleton screens or placeholders that match final content dimensions
Quick tip: Modern browsers automatically calculate aspect ratio from width and height attributes, even if you override dimensions with CSS. Always include these attributes.
Problem 2: Ads, Embeds, and Iframes
Third-party content like ads, social media embeds, and iframes often load after the initial page render, pushing content down.
Solutions:
- Reserve space for ad slots with fixed dimensions or aspect ratios
- Use
min-heighton containers for dynamic content - Load ads and embeds below the fold when possible
- Use placeholder elements that match the final content size
- Implement lazy loading for below-the-fold embeds
Problem 3: Web Fonts Causing FOUT/FOIT
Flash of Unstyled Text (FOUT) or Flash of Invisible Text (FOIT) occurs when web fonts load, causing text to reflow and shift layout.
Solutions:
- Use
font-display: optionalto prevent layout shift (uses fallback if font isn't cached) - Preload critical fonts with
<link rel="preload" as="font"> - Use system fonts for body text, custom fonts only for headings
- Match fallback font metrics to custom fonts using
size-adjust,ascent-override, etc. - Consider variable fonts to reduce the number of font files
Problem 4: Dynamically Injected Content
Content added to the page via JavaScript (banners, notifications, cookie consent) often causes layout shifts.
Solutions:
- Use fixed or sticky positioning for banners and notifications
- Animate new content in using transforms (which don't affect layout)
- Reserve space for dynamic content in the initial layout
- Use
position: absoluteorposition: fixedfor overlays - Implement smooth transitions with
transformandopacityinstead of changing layout properties
Problem 5: Animations Triggering Layout
Animating properties like width, height, top, or left triggers layout recalculation on every frame.
Solutions:
- Use
transformandopacityfor animations (GPU-accelerated, no layout) - Use
will-changeCSS property to hint at upcoming animations - Implement animations with CSS transitions or animations instead of JavaScript when possible
- Use
requestAnimationFrame()for JavaScript animations - Consider the Web Animations API for complex, performant animations
Advanced CLS Optimization
Container Queries: Use CSS Container Queries to create responsive components that don't cause layout shifts when container size changes.
Content-Visibility: The content-visibility: auto CSS property allows the browser to skip rendering off-screen content, reducing layout work and potential shifts.
Intersection Observer: Use the Intersection Observer API to load content just before it enters the viewport, giving you time to reserve space without loading everything upfront.
How to Measure Core Web Vitals
Measuring Core Web Vitals requires both lab data (synthetic testing) and field data (real user monitoring). Each approach has strengths and weaknesses, and you need both for a complete picture.
Field Data (Real User Monitoring)
Field data comes from actual users visiting your site with their real devices, network conditions, and usage patterns. This is what Google uses for ranking.
Chrome User Experience Report (CrUX): Google's official dataset of real-world Chrome user experiences. Access it through:
- PageSpeed Insights (shows CrUX data for your URL)
- Search Console Core Web Vitals report (shows issues across your site)
- CrUX Dashboard (visualize trends over time)
- CrUX API (programmatic access to data)
Real User Monitoring (RUM) Tools: Implement your own monitoring to get more detailed insights:
- Google Analytics 4 with Web Vitals library
- Cloudflare Web Analytics
- New Relic Browser Monitoring
- Datadog Real User Monitoring
- SpeedCurve LUX
Pro tip: Use our Core Web Vitals Checker to quickly see your CrUX data and identify pages that need attention.
Lab Data (Synthetic Testing)
Lab data comes from controlled tests in simulated environments. It's great for debugging and development but doesn't reflect real-world variability.
Chrome DevTools: Built into Chrome, provides detailed performance traces and Core Web Vitals measurements. Use Lighthouse for automated audits.
PageSpeed Insights: Combines Lighthouse lab data with CrUX field data. Shows both what's happening and what could be improved.
WebPageTest: Advanced testing tool with detailed waterfall charts, filmstrip views, and the ability to test from different locations and devices.
Lighthouse CI: Integrate Lighthouse into your CI/CD pipeline to catch performance regressions before they reach production.
Setting Up Monitoring
Here's a practical approach to comprehensive Core Web Vitals monitoring:
- Implement RUM: Add the web-vitals JavaScript library to track real user experiences
- Set up alerts: Configure notifications when metrics exceed thresholds
- Create dashboards: Visualize trends over time, segmented by device, country, and page type
- Integrate with CI/CD: Run Lighthouse tests on every deployment
- Regular audits: Schedule monthly deep-dives into performance data
Use our