Optimization

Core Web Vitals Optimization: LCP, INP, CLS Complete Guide (2025)

Master Core Web Vitals optimization for 2025. Complete guide to improving LCP, INP, and CLS for better SEO rankings, user experience, and conversions with actionable techniques.

  • 22 min read
  • Updated:
  • By Convert a Document
In this guide:

Master Core Web Vitals optimization for 2025. Complete guide to improving LCP, INP, and CLS for better SEO rankings, user experience, and conversions with actionable techniques.

Your website's Core Web Vitals scores directly impact your Google search rankings, conversion rates, and revenue. In March 2024, Google made a critical change--nearly 600,000 websites that previously passed suddenly failed when Interaction to Next Paint (INP) replaced First Input Delay (FID). If you haven't optimized for the 2025 Core Web Vitals metrics, you're losing traffic and money to competitors who have. This guide shows you exactly how to optimize LCP, INP, and CLS to pass Google's thresholds and keep your rankings.

What Are Core Web Vitals?

Core Web Vitals are Google's official metrics for measuring real-world user experience on your website. They became a ranking factor in June 2021 and directly affect your search positions.

The Three Core Web Vitals for 2025

Metric What It Measures Good Score Impact
LCP
(Largest Contentful Paint)
How fast your main content loads Under 2.5 seconds Loading performance
INP
(Interaction to Next Paint)
How quickly page responds to user interactions Under 200 milliseconds Interactivity & responsiveness
CLS
(Cumulative Layout Shift)
Visual stability during page load Under 0.1 Visual stability

March 2024 Major Change: INP Replaced FID

Google officially replaced First Input Delay (FID) with Interaction to Next Paint (INP) in March 2024. INP is a stricter metric that measures responsiveness throughout the entire page lifecycle, not just the first interaction. 600,000 websites went from passing to failing when this change took effect.

If you haven't optimized for INP yet, you're likely failing this metric and losing rankings.

Why Core Web Vitals Matter in 2025

  • Direct ranking factor - Google uses these scores to determine search positions (especially mobile-first indexing)
  • Revenue impact - The Economic Times improved CLS by 250% and reduced bounce rates by 43%
  • Conversion rates - Every 0.1 second delay in mobile page load decreases conversion rates by 8.4%
  • User satisfaction - 53% of mobile users abandon sites that take longer than 3 seconds to load
  • Mobile-first indexing - Google ranks based on your mobile scores, not desktop
  • Competitive advantage - Sites with better Core Web Vitals outrank slower competitors with similar content

LCP Optimization: Largest Contentful Paint

LCP measures how long it takes for the largest visible element (hero image, heading, video) to appear on screen. Good LCP is under 2.5 seconds; poor LCP is over 4 seconds.

What Counts as LCP Element?

The browser considers these elements for LCP:

  • <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 or inline text elements

Common LCP Problems and Fixes

Problem 1: Slow Server Response Time

Symptom: Time to First Byte (TTFB) over 600ms

Solutions:

  • Upgrade hosting: Move from shared hosting to VPS or managed WordPress hosting (WP Engine, Kinsta, Cloudways)
  • Use CDN: Cloudflare, CloudFront, or platform-specific CDNs distribute content closer to users
  • Enable caching: Browser caching, server-side caching (Redis, Varnish)
  • Optimize database: Clean up revisions, optimize tables, add indexes
  • Reduce redirects: Each redirect adds 200-600ms delay

Problem 2: Render-Blocking Resources

Symptom: CSS and JavaScript files blocking page render

Solutions:

  • Inline critical CSS: Extract above-the-fold CSS and inline it in <head>
  • Defer non-critical CSS: Load below-the-fold styles asynchronously
  • Defer JavaScript: Add defer or async attributes to non-critical scripts
  • Minimize CSS/JS: Use minification and compression (Gzip, Brotli)
  • Remove unused code: Audit with Coverage tool in Chrome DevTools

Example: Defer Non-Critical CSS

<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>

Problem 3: Large LCP Element (Hero Image)

Symptom: Hero image is 2-5 MB and takes 3+ seconds to load

Solutions:

  • Optimize image size: Compress to 80-90% quality, target under 200KB for hero images
  • Use modern formats: WebP reduces size by 25-35%, AVIF by 50% vs JPEG
  • Responsive images: Serve different sizes with srcset and sizes
  • Preload LCP image: Tell browser to prioritize loading
  • Use CDN: Serve images from geographically distributed servers
  • Proper dimensions: Set width and height attributes to prevent layout shifts

Example: Preload Hero Image

<link rel="preload" as="image" href="hero.webp"
      imagesrcset="hero-mobile.webp 640w, hero-tablet.webp 1024w, hero.webp 1920w"
      imagesizes="100vw">

Example: Responsive Images

<img src="hero-1920.webp"
     srcset="hero-640.webp 640w, hero-1024.webp 1024w, hero-1920.webp 1920w"
     sizes="100vw"
     alt="Hero image"
     width="1920"
     height="1080">

Problem 4: Web Fonts Blocking Render

Symptom: Text not appearing until custom fonts load (FOIT - Flash of Invisible Text)

Solutions:

  • Preload fonts: Priority load for critical fonts
  • Font-display: swap: Show fallback font immediately, swap when custom font loads
  • Subset fonts: Include only characters you actually use (reduces file size 60-80%)
  • Self-host fonts: Avoid third-party requests to Google Fonts (save 200-400ms)
  • Use system fonts: Consider using system font stack for body text

Example: Preload and Optimize Fonts

<link rel="preload" href="/fonts/roboto-subset.woff2" as="font" type="font/woff2" crossorigin>

<style>
@font-face {
  font-family: 'Roboto';
  src: url('/fonts/roboto-subset.woff2') format('woff2');
  font-display: swap;
  unicode-range: U+0020-007F; /* Latin subset only */
}
</style>

LCP Quick Wins Checklist

  1. ✅ Optimize hero image (compress to <200KB, use WebP/AVIF)
  2. ✅ Preload LCP element with <link rel="preload">
  3. ✅ Use CDN for images and static assets
  4. ✅ Inline critical CSS (above-the-fold styles)
  5. ✅ Defer non-critical JavaScript
  6. ✅ Optimize server response time (TTFB under 600ms)
  7. ✅ Enable text compression (Gzip or Brotli)
  8. ✅ Remove render-blocking resources
  9. ✅ Set explicit width/height on images
  10. ✅ Use font-display: swap for web fonts

INP Optimization: Interaction to Next Paint

INP measures how quickly your page responds to user interactions (clicks, taps, keyboard input). Good INP is under 200ms; poor INP is over 500ms. INP replaced FID in March 2024 and is more demanding.

Why INP Is Harder Than FID

  • FID measured first interaction only - INP measures ALL interactions throughout page lifecycle
  • FID accepted 100ms - INP requires under 200ms (stricter)
  • FID ignored subsequent sluggishness - INP catches all responsiveness issues
  • More comprehensive - Scroll, hover, continuous interactions all count

Common INP Problems and Fixes

Problem 1: Long JavaScript Tasks

Symptom: Main thread blocked by JavaScript execution over 50ms

Solutions:

  • Break up long tasks: Split tasks over 50ms into smaller chunks with setTimeout() or requestIdleCallback()
  • Code splitting: Load JavaScript on-demand instead of one massive bundle
  • Remove unnecessary JavaScript: Audit third-party scripts (analytics, ads, chat widgets)
  • Web Workers: Move heavy computation off main thread
  • Lazy load non-critical scripts: Defer loading until actually needed

Example: Break Long Task

// Bad: Blocks main thread
for (let i = 0; i < 10000; i++) {
  processItem(items[i]);
}

// Good: Yields to browser between chunks
async function processItemsAsync() {
  for (let i = 0; i < items.length; i++) {
    processItem(items[i]);

    // Yield every 50 items
    if (i % 50 === 0) {
      await new Promise(resolve => setTimeout(resolve, 0));
    }
  }
}

Problem 2: Heavy Event Handlers

Symptom: Click or scroll events trigger expensive operations

Solutions:

  • Debounce/Throttle: Limit how often event handlers fire
  • Passive event listeners: Mark scroll/touch events as passive
  • Request Animation Frame: Schedule visual updates efficiently
  • Event delegation: Use single handler on parent instead of many on children
  • Optimize DOM manipulation: Batch updates, use DocumentFragment

Example: Debounce Scroll Handler

// Debounce utility
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, args), wait);
  };
}

// Use debounced handler
window.addEventListener('scroll', debounce(() => {
  // Expensive scroll logic here
  updateParallax();
}, 100));

Example: Passive Event Listener

// Improves scroll performance
window.addEventListener('scroll', handleScroll, { passive: true });
window.addEventListener('touchstart', handleTouch, { passive: true });

Problem 3: Large DOM Size

Symptom: DOM tree has 1,500+ nodes, slowing down rendering and interaction

Solutions:

  • Limit DOM depth: Avoid deeply nested elements (target max 32 levels)
  • Virtual scrolling: Render only visible items in long lists
  • Remove hidden elements: Actually remove from DOM, don't just hide with CSS
  • Lazy render sections: Render below-fold content after initial load
  • Simplify HTML structure: Remove unnecessary wrapper divs

Target DOM Metrics:

  • Total nodes: Under 1,500
  • DOM depth: Under 32 levels
  • Parent nodes with children: Under 60

Problem 4: Third-Party Scripts Blocking Interaction

Symptom: Analytics, ads, chat widgets delay page responsiveness

Solutions:

  • Load asynchronously: Use async or defer on script tags
  • Delay non-critical scripts: Load after page interactive
  • Self-host when possible: Avoid network requests to third parties
  • Use facades: Lazy load YouTube embeds, social widgets
  • Remove unnecessary scripts: Audit what you actually need
  • Monitor impact: Use Request Blocking in DevTools to test performance without each script

Example: Delay Third-Party Scripts

// Load analytics after page interactive
window.addEventListener('load', () => {
  setTimeout(() => {
    // Load Google Analytics
    const script = document.createElement('script');
    script.src = 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID';
    script.async = true;
    document.head.appendChild(script);
  }, 3000); // 3 second delay
});

INP Quick Wins Checklist

  1. ✅ Break JavaScript tasks longer than 50ms into chunks
  2. ✅ Defer non-critical third-party scripts
  3. ✅ Debounce/throttle scroll and resize handlers
  4. ✅ Use passive event listeners for scroll/touch
  5. ✅ Reduce DOM size (under 1,500 nodes)
  6. ✅ Code-split large JavaScript bundles
  7. ✅ Remove unused JavaScript (tree shaking)
  8. ✅ Optimize event handlers (delegation, minimal logic)
  9. ✅ Use Web Workers for heavy computation
  10. ✅ Lazy load below-the-fold JavaScript

CLS Optimization: Cumulative Layout Shift

CLS measures visual stability--how much content unexpectedly moves during page load. Good CLS is under 0.1; poor CLS is over 0.25. Every unexpected layout shift frustrates users and harms conversions.

What Causes Layout Shifts?

  • Images without dimensions
  • Ads, embeds, iframes without reserved space
  • Web fonts causing FOIT/FOUT (Flash of Invisible/Unstyled Text)
  • Dynamically injected content above existing content
  • Actions that trigger network requests before page fully loaded

Common CLS Problems and Fixes

Problem 1: Images Without Dimensions

Symptom: Content jumps down when images load

Solution: Always set width and height attributes on <img> tags

Bad (causes CLS):

<img src="hero.jpg" alt="Hero">

Good (prevents CLS):

<img src="hero.jpg" alt="Hero" width="1920" height="1080">

Modern browsers automatically calculate aspect ratio from width/height and reserve space, even with CSS making images responsive.

CSS for Responsive Images:

img {
  max-width: 100%;
  height: auto;
}

Problem 2: Ads and Embeds Causing Shifts

Symptom: Content jumps when ads or YouTube embeds load

Solutions:

  • Reserve space with min-height: Set minimum dimensions for ad slots
  • Use aspect-ratio boxes: CSS aspect-ratio or padding-bottom trick
  • Placeholder elements: Show skeleton screens while loading
  • Avoid inserting content above fold: New content should appear below existing

Example: Reserve Space for Ad

<div class="ad-container" style="min-height: 250px;">
  <!-- Ad loads here -->
</div>

Example: YouTube Embed with Aspect Ratio

<div style="aspect-ratio: 16 / 9;">
  <iframe src="https://youtube.com/embed/..."
          width="100%" height="100%"></iframe>
</div>

Problem 3: Web Fonts Causing Layout Shift

Symptom: Text reflows when custom font loads, changing line breaks and layout

Solutions:

  • font-display: optional: Only use custom font if it loads quickly, otherwise stick with fallback
  • Match fallback font metrics: Adjust fallback font size to match custom font
  • Preload critical fonts: Ensure fonts load before text renders
  • Font subsetting: Smaller file = faster load = less shift

Example: Match Fallback Font Size

@font-face {
  font-family: 'CustomFont';
  src: url('custom.woff2') format('woff2');
  font-display: optional;
}

body {
  font-family: 'CustomFont', Arial, sans-serif;
  /* Adjust to match CustomFont metrics */
  font-size: 16px;
  line-height: 1.5;
}

CSS Font Loading API:

// Ensure font loaded before showing text
document.fonts.load('16px CustomFont').then(() => {
  document.body.classList.add('fonts-loaded');
});

Problem 4: Dynamic Content Injection

Symptom: Banners, notifications, cookie consent shifting content down

Solutions:

  • Use overlays: Position absolutely or fixed instead of pushing content
  • Reserve space on page load: Even if content loads later
  • Insert at bottom: Append new content below visible area
  • Animate with transform: Use CSS transform instead of changing dimensions

Example: Fixed Position Banner (No CLS)

.cookie-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  /* Doesn't push content - overlays instead */
}

CLS Quick Wins Checklist

  1. ✅ Set width and height on ALL images
  2. ✅ Reserve space for ads and embeds (min-height or aspect-ratio)
  3. ✅ Use font-display: optional or font-display: swap
  4. ✅ Preload critical fonts
  5. ✅ Avoid injecting content above existing content
  6. ✅ Use overlays/fixed position for banners
  7. ✅ Set dimensions on video embeds
  8. ✅ Avoid animations that change dimensions (use transform)
  9. ✅ Load below-fold images with lazy loading
  10. ✅ Reserve skeleton space for dynamic content

Testing and Measuring Core Web Vitals

Essential Testing Tools

1. PageSpeed Insights (Free, Official Google Tool)

URL: https://pagespeed.web.dev/

What it does:

  • Tests both mobile and desktop
  • Shows field data (real users) and lab data (simulated)
  • Provides specific recommendations
  • Shows if you're passing Core Web Vitals thresholds

How to use:

  1. Enter your URL
  2. Click "Analyze"
  3. Check "Core Web Vitals Assessment" (pass/fail)
  4. Review "Opportunities" and "Diagnostics" sections
  5. Fix issues, retest until passing

2. Chrome DevTools (Built-in Browser Tool)

Best for: Detailed debugging and real-time testing

Key Features:

  • Performance tab: Record page load, identify bottlenecks
  • Lighthouse: Run audits directly in browser
  • Coverage: Find unused CSS/JavaScript
  • Network tab: See resource load times and sizes
  • Rendering tab: Paint flashing, layout shift regions

How to test CLS in DevTools:

  1. Open DevTools (F12)
  2. Click three dots → More tools → Rendering
  3. Enable "Layout Shift Regions"
  4. Reload page and see blue highlights where shifts occur

3. Google Search Console (Real User Data)

Best for: See how real users experience your site

What it shows:

  • Core Web Vitals report for your entire site
  • Mobile vs Desktop performance
  • URLs grouped by issue type
  • Historical trends (how you're improving)

How to use:

  1. Open Google Search Console
  2. Navigate to Core Web Vitals report
  3. Review "Poor URLs" that fail thresholds
  4. Click groups to see specific failing pages
  5. Fix issues, wait 28 days for new data

4. Web Vitals Chrome Extension

Install: Chrome Web Store → "Web Vitals"

What it does:

  • Shows LCP, INP, CLS in real-time as you browse
  • HUD overlay on every page
  • Instant feedback while developing

Mobile vs Desktop Testing

Critical: Google Uses Mobile Scores for Rankings

Google's mobile-first indexing means your mobile Core Web Vitals determine your search rankings, not desktop. Many sites pass on desktop but fail on mobile.

Always test:

  • Real mobile devices (not just DevTools mobile emulation)
  • Slow 3G/4G connections (not just WiFi)
  • Various phone models (flagship and budget Android)

Platform-Specific Optimization

WordPress Core Web Vitals Optimization

Essential Plugins:

  • WP Rocket: Comprehensive caching, minification, lazy loading, CDN integration
  • Imagify or ShortPixel: Automatic image compression and WebP conversion
  • Perfmatters: Disable unnecessary features, defer JavaScript, optimize database
  • Asset CleanUp: Disable CSS/JS on pages that don't need them

Quick WordPress Fixes:

  1. Upgrade hosting: Shared hosting won't cut it (use managed WP hosting)
  2. Use lightweight theme: GeneratePress, Astra, Kadence
  3. Limit plugins: Deactivate and delete unused plugins
  4. Optimize database: WP-Optimize plugin
  5. Enable lazy loading: Built-in since WP 5.5, or use WP Rocket
  6. Use object caching: Redis or Memcached
  7. Defer JavaScript: WP Rocket or Autoptimize

Shopify Core Web Vitals Optimization

Shopify-Specific Challenges:

  • Limited control over server-side code
  • Heavy theme JavaScript for product pages
  • Third-party app scripts

Shopify Optimization Strategies:

  1. Choose fast theme: Dawn (default), Sense, Studio (designed for speed)
  2. Remove unused apps: Each app adds scripts; audit regularly
  3. Optimize images: Shopify CDN handles basic optimization, but compress before upload
  4. Use native lazy loading: Shopify 2.0 themes support this
  5. Defer third-party scripts: Load after page interactive
  6. Minimize sections: Shopify sections add HTML/CSS; keep homepage lean
  7. Use Cloudflare: Add CDN layer on top of Shopify

React/Next.js Core Web Vitals Optimization

Next.js Advantages:

  • Built-in image optimization with next/image
  • Automatic code splitting
  • Server-side rendering (SSR) for faster LCP
  • Font optimization

Next.js Best Practices:

  1. Use next/image: Automatic optimization, lazy loading, modern formats
  2. Enable Static Generation (SSG): Pre-render pages at build time
  3. Dynamic imports: Load components on-demand
  4. Optimize fonts: Use next/font for automatic font optimization
  5. Monitor bundle size: Use @next/bundle-analyzer

Example: Next.js Image Optimization

import Image from 'next/image'

export default function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero image"
      width={1920}
      height={1080}
      priority // Preload LCP image
      placeholder="blur" // Blur-up placeholder
    />
  )
}

Real-World Case Studies

Case Study 1: The Economic Times (News Site)

Results:

  • CLS improved by 250% (from 0.25 to 0.09)
  • LCP improved by 80% (to 2.5 seconds)
  • Bounce rate reduced by 43%

What they did:

  • Set explicit dimensions on all images and ads
  • Optimized font loading with font-display: swap
  • Preloaded hero images
  • Reserved space for dynamic ad units
  • Implemented lazy loading for below-fold content

Case Study 2: E-commerce Site (Anonymous)

Starting Point:

  • LCP: 4.2 seconds (poor)
  • INP: 380ms (poor)
  • CLS: 0.18 (needs improvement)

After Optimization:

  • LCP: 2.1 seconds (good) - 50% improvement
  • INP: 180ms (good) - 53% improvement
  • CLS: 0.05 (good) - 72% improvement

Business Impact:

  • Conversion rate increased 11%
  • Organic traffic up 23% (better rankings)
  • Mobile revenue up 31%

Key optimizations:

  • Migrated to faster hosting (Cloudways)
  • Converted all product images to WebP
  • Implemented CDN (Cloudflare)
  • Deferred third-party scripts (Facebook Pixel, Google Ads)
  • Reduced JavaScript bundle size by 60%

Quick Reference: Core Web Vitals Thresholds

Metric Good Needs Improvement Poor
LCP ≤ 2.5s 2.5s - 4.0s > 4.0s
INP ≤ 200ms 200ms - 500ms > 500ms
CLS ≤ 0.1 0.1 - 0.25 > 0.25

Passing Threshold

To pass Core Web Vitals assessment, 75% of page views must meet the "Good" threshold for all three metrics. This is measured at the 75th percentile of field data (real users).

Wrapping Up: Your Core Web Vitals Action Plan

Core Web Vitals directly impact your revenue, rankings, and user satisfaction. Here's your step-by-step action plan:

30-Day Optimization Plan

Week 1: Measure and Prioritize

  1. Test all key pages in PageSpeed Insights
  2. Check Search Console Core Web Vitals report
  3. Identify failing pages and common issues
  4. Prioritize high-traffic pages first

Week 2: LCP Optimization

  1. Optimize hero images (compress, use WebP, preload)
  2. Enable CDN for images and static assets
  3. Inline critical CSS
  4. Defer non-critical JavaScript
  5. Optimize server response time (upgrade hosting if needed)

Week 3: INP and CLS Optimization

  1. Set width/height on all images
  2. Reserve space for ads and embeds
  3. Optimize font loading (preload, font-display: swap)
  4. Break up long JavaScript tasks
  5. Defer third-party scripts
  6. Reduce DOM size

Week 4: Test, Refine, Monitor

  1. Retest all pages in PageSpeed Insights
  2. Test on real mobile devices
  3. Fix any remaining issues
  4. Set up ongoing monitoring
  5. Wait 28 days for Search Console to reflect changes

Key Takeaways

  • Mobile scores matter most - Google ranks based on mobile performance
  • INP is the new challenge - More demanding than FID; focus on JavaScript optimization
  • Images are usually the culprit - Optimize, compress, set dimensions, use modern formats
  • Real user data beats lab data - Monitor Search Console for real-world performance
  • Small improvements = big impact - Every 0.1s improvement in LCP can boost conversions
  • Test continuously - Performance degrades over time; monitor and maintain

Additional Resources

  • Official Google Documentation: web.dev/vitals/
  • PageSpeed Insights: pagespeed.web.dev
  • Google Search Console: Monitor real user Core Web Vitals
  • Web Vitals Chrome Extension: Real-time monitoring while browsing

Ready to optimize?

Use Convert a Document to shrink files without sacrificing quality.

Related articles

About Convert a Document

Convert a Document helps you understand, convert, and optimize files with simple tools and clear guidance for everyday workflows.