How to Fix Core Web Vitals

How to Fix Core Web Vitals

How to Fix Core Web Vitals & Pass Google's Page Experience

Core Web Vitals are Google's three official performance metrics. They measure how fast your page loads, how quickly it responds to user input, and how stable the layout is while loading.

If any one of them is failing, you are likely losing rankings, losing users, and losing conversions — even if your content is excellent.

This guide covers everything: what each metric measures, how to diagnose which one is failing, and exactly how to fix it. Platform-specific fixes for WordPress, Shopify, and Next.js are included at the end.

What are Core Web Vitals?

Core Web Vitals are three specific metrics Google uses to measure real-world user experience. They became official ranking signals in 2021 as part of Google's Page Experience update.

The three metrics are:

  • LCP (Largest Contentful Paint) — measures loading performance. How long does it take for the largest visible element on screen to fully load?
  • INP (Interaction to Next Paint) — measures interactivity. How long does it take for the page to visually respond after a user clicks, taps, or types?
  • CLS (Cumulative Layout Shift) — measures visual stability. How much does the page content unexpectedly jump around while loading?

Here are the scoring thresholds for each:

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

Google measures all three at the 75th percentile of real users. That means 75% of your visitors need to have a good experience — not just the average visitor.

Do Core Web Vitals affect rankings?

Yes — but they are a tiebreaker, not the primary ranking factor. When two pages cover the same topic with similar content quality, the one with better CWV scores will rank higher.

Beyond rankings, poor CWV directly hurts your business. A 100ms delay in page response reduces conversions by around 7%. High CLS causes users to click the wrong thing and leave. Poor INP makes your site feel broken even when it technically works.

How to diagnose your Core Web Vitals

Before you fix anything, find out exactly which metric is failing and on which pages. Guessing wastes time.

Lab data vs field data — know the difference first

This is the most important concept before you start:

  • Lab data is a simulated test. Tools like Lighthouse and PageSpeed Insights run a controlled test from a fixed location, on a fixed device, on a fixed connection. Great for debugging — but not what Google scores you on.
  • Field data (CrUX — Chrome User Experience Report) is collected from real users visiting your site. Actual devices, actual connection speeds, actual geography. This is what Google uses for rankings.

Always check field data first to confirm you have a real problem. Then use lab data to diagnose why.

Step 1: Check Google Search Console

  1. Go to Google Search Console → Experience → Core Web Vitals
  2. Check both Mobile and Desktop reports — Google scores them separately
  3. Click into "Poor URLs" to see which pages are failing
  4. Note which metric is flagged — this tells you where to focus

Step 2: Run PageSpeed Insights

Paste a failing URL into pagespeed.web.dev. You will see two sections:

  • "Discover what your real users are experiencing" — field data from CrUX. Your actual scores.
  • "Diagnose performance issues" — Lighthouse lab data. Lists specific issues with estimated time savings for each fix.

The Diagnostics section maps every issue to the metric it affects. This is where you will spend most of your time.

Core diagnostic tools

Tool Best For
PageSpeed Insights Best starting point — lab + field data together
Google Search Console Real-user field data across all your URLs
Chrome DevTools Performance panel Deep debugging for INP long tasks and CLS
Web Vitals Chrome extension Live CWV overlay as you browse your site
Lighthouse CLI Automated testing in CI/CD pipelines

Pro tip: Do not chase a perfect Lighthouse score. A score of 90+ in the lab means nothing if your field data is still poor. Fix the field data first.

How to fix LCP (Largest Contentful Paint)

LCP is the most commonly failing Core Web Vital. The target is 2.5 seconds or less. Most LCP problems come down to one of four root causes.

What counts as the LCP element?

PageSpeed Insights will show you exactly what your LCP element is. The most common ones are:

  • Hero images (by far the most common — especially on ecommerce and landing pages)
  • Large above-the-fold text blocks
  • Background images loaded via CSS
  • Video poster images

The 4 phases of LCP — where time is being lost

Google breaks LCP into four phases. Knowing which phase is slow tells you exactly which fix to apply:

  1. Time to First Byte (TTFB) — server is responding slowly
  2. Resource load delay — browser is not discovering the LCP image early enough
  3. Resource load time — the image itself is too large or too slow to download
  4. Element render delay — JavaScript is blocking the element from painting

Fix 1: Improve your server response time (TTFB)

If your TTFB is above 800ms, your server is the bottleneck. Everything else you do will be limited by how long the server takes to respond.

  • Use a CDN. A Content Delivery Network serves your pages from servers physically closer to each user. This alone can cut TTFB by 50–70% for users far from your origin server.
  • Enable full-page caching. For WordPress: WP Rocket, LiteSpeed Cache, or W3 Total Cache. For custom sites: Varnish, Redis, or your hosting provider's built-in caching.
  • Upgrade your hosting. Shared hosting is the single biggest TTFB killer for WordPress sites. Moving to managed hosting (Kinsta, WP Engine, Cloudways) often cuts TTFB from 1,500ms to under 200ms overnight.

Fix 2: Preload your LCP image

This is the highest-impact, lowest-effort LCP fix available. Add this in the <head> of your page, before any stylesheets:

<link rel="preload" as="image" href="/your-hero-image.webp" fetchpriority="high">

Also add the fetchpriority attribute directly on the <img> tag:

<img src="hero.webp" fetchpriority="high" alt="Hero image">

Critical mistake to avoid: Never add loading="lazy" to your LCP image. Lazy loading tells the browser to delay loading the image — the exact opposite of what you want for your most important element.

Fix 3: Compress and convert your images

Even with preloading, a 2MB hero image will never hit a 2.5s LCP target on mobile.

  • Convert to WebP or AVIF. WebP is typically 30–50% smaller than JPEG at the same visual quality. Use WebP as your default.
  • Compress aggressively. For most hero images, 80% quality in WebP is indistinguishable from 100%. Use Squoosh, ImageOptim, or an automated pipeline like Cloudinary.
  • Use srcset for responsive images. There is no reason to send a 2,400px image to a phone.
  • Set explicit width and height attributes. This also prevents CLS (covered below).

Fix 4: Eliminate render-blocking resources

Render-blocking resources prevent the browser from painting anything until they finish loading.

  • Inline critical CSS. CSS needed to render above-the-fold content should go directly in a <style> tag in the <head>.
  • Defer non-critical JavaScript. Add the defer attribute to any <script> tag not needed for the initial render.
  • Async third-party scripts. Add async to analytics, chat widgets, and marketing pixels. Never load these synchronously.

LCP quick wins: Preload the hero image with fetchpriority="high" → Remove loading="lazy" from the LCP element → Convert images to WebP → Add a CDN → Enable server-side caching

How to fix INP (Interaction to Next Paint)

INP replaced FID as an official Core Web Vital in March 2024. The target is 200ms or less.

INP measures the worst interaction across an entire page session — not just the first click. This makes it significantly harder to pass than FID, especially for JavaScript-heavy sites.

What causes poor INP?

Almost all INP problems have the same root cause: the browser's main thread is busy doing JavaScript work when the user tries to interact.

  • Long JavaScript tasks. Any task running for more than 50ms on the main thread is a "long task." It directly delays the browser's response to user input.
  • Heavy third-party scripts. Analytics, chat widgets, advertising tags, and A/B testing tools all run on the main thread. If they fire when a user clicks something, the click response is delayed.
  • Expensive event handlers. Event listeners that trigger layout recalculations can block the main thread for hundreds of milliseconds.
  • Large DOM size. Pages with more than 1,400 DOM nodes take significantly longer to recalculate styles after an interaction.

Fix 1: Break up long tasks

Open Chrome DevTools → Performance panel → record a session where you click around the page. Look for red-topped bars in the Main thread timeline — these are long tasks.

To break them up, yield back to the browser between chunks of work:

// Instead of one blocking function:
async function processLargeList(items) {
  for (const item of items) {
    heavyWork(item);
    await scheduler.yield(); // gives the browser a chance to respond
  }
}

Use setTimeout(fn, 0) as a fallback for browsers that do not support scheduler.yield() yet.

Fix 2: Reduce and defer third-party scripts

Third-party scripts are often the biggest INP killer — and they are entirely outside your codebase.

  1. Open PageSpeed Insights and look for "Reduce the impact of third-party code"
  2. Audit the list honestly — remove scripts from tools you no longer actively use
  3. For scripts you keep: load them after the page is interactive using defer or by injecting them after the load event
  4. For scripts that must run early: consider Partytown, which offloads third-party scripts to a web worker

Reality check: A typical marketing site loads 10–20 third-party scripts. Each one competes for main thread time. If your INP is failing, at least one third-party script is almost certainly responsible.

Fix 3: Optimise your event handlers

  • Debounce scroll and resize handlers. These fire hundreds of times per second without debouncing.
  • Avoid layout thrashing. Never read offsetWidth, offsetHeight, or getBoundingClientRect inside a loop or immediately after writing to the DOM.
  • Use CSS for animations, not JavaScript. CSS animations run on the compositor thread and do not block user interactions.
  • Reduce React re-renders. Use React.memo, useMemo, and useCallback to prevent unnecessary re-renders on interaction.

INP quick wins: Find long tasks in DevTools Performance panel → Audit and remove unused third-party scripts → Defer remaining third-party scripts until after page load → Add scheduler.yield() to long synchronous functions

How to fix CLS (Cumulative Layout Shift)

CLS measures how much your page content unexpectedly shifts while loading. A score above 0.1 means users are seeing visible instability — buttons moving, text jumping, links shifting just as they are about to click.

The target is 0.1 or less. CLS is the most fixable of the three vitals once you know what is causing it.

What causes layout shift?

  • Images without explicit dimensions. The browser allocates no space for an image until it loads. When it does load, it pushes everything below it down.
  • Web fonts causing FOUT/FOIT. When a custom font swaps in, text reflows if the fallback font has different dimensions.
  • Dynamically injected content. Cookie banners, promo bars, chat widgets, and ad slots inserted above existing content after page load push everything down.
  • Animating layout properties. Animating top, left, width, or height triggers layout recalculation. Only animate transform and opacity.

Fix 1: Add explicit dimensions to all images and videos

This is the single highest-impact CLS fix for most websites:

html

<img src="hero.webp" width="1200" height="600" alt="Hero image" fetchpriority="high">

For responsive images, combine explicit dimensions with CSS:

css

img {
  width: 100%;
  height: auto; /* browser uses width/height to calculate aspect ratio */
}

If you do not know the exact dimensions (user-uploaded images), use aspect-ratio:

css

.image-container {
  aspect-ratio: 16 / 9;
  width: 100%;
  overflow: hidden;
}

Fix 2: Fix font-induced layout shift

  • Use font-display: optional. The browser uses the fallback font if the custom font is not cached. Zero layout shift — users on their first visit see the fallback font.
  • Preload key fonts. Add <link rel="preload" as="font" type="font/woff2" crossorigin> in <head> for any font used above the fold.
  • Use size-adjust. If you usefont-display: swap, pair it with size-adjust, ascent-override, and descent-override to match the fallback font's metrics to your custom font.

Fix 3: Reserve space for dynamic content

  • Give ad slots a fixed minimum height. Even before the ad loads, give the container a min-height matching the ad unit size.
  • Use position: fixed for cookie banners. A fixed banner overlays content instead of pushing it down.
  • Never inject promo bars via JavaScript after page load. Include them in the initial HTML so the browser accounts for their height from the start.

CLS quick wins: Add width and height to every img and video → Add aspect-ratio CSS to responsive containers → Preload above-the-fold fonts → Give ad slots a min-height → Animate only transform and opacity

Platform-specific fixes

WordPress

WordPress is where Core Web Vitals problems are most common — primarily because of plugin bloat and unoptimised themes.

  • Install a caching plugin. WP Rocket is the most complete all-in-one solution (paid). LiteSpeed Cache is free and excellent if your host runs LiteSpeed.
  • Install an image optimisation plugin. Imagify, ShortPixel, or Smush automatically convert images to WebP and compress them on upload.
  • Switch to a lightweight theme. GeneratePress, Kadence, and Blocksy load under 50KB. Most popular themes (Divi, Avada) ship with hundreds of kilobytes you do not need.
  • Audit and remove unused plugins. Every active plugin adds JavaScript and CSS to your pages, even pages where it is not needed.
  • Add a CDN. Cloudflare's free plan cuts TTFB by 50% or more for international users.

Shopify

Shopify manages hosting for you, so TTFB is rarely the issue. The problems come from themes and apps.

  • Choose a lightweight theme. Dawn (Shopify's free default) is well-optimised. Many third-party themes ship with jQuery and multiple CSS frameworks that hurt performance.
  • Audit your apps aggressively. Each installed Shopify app typically adds 50–200ms of JavaScript execution. Remove any app you are not actively using.
  • Never lazy-load your main product image. It is almost always the LCP element. Keep it loading="eager".

Next.js and React

React apps often have good lab scores but poor INP in the field. React's rendering model creates long tasks on interaction.

  • Use next/image for all images. It automatically handles WebP, lazy loading, explicit dimensions, and CDN delivery.
  • Use dynamic imports. next/dynamic code-splits heavy components so they only load when needed.
  • Profile React re-renders. Use React DevTools Profiler to find components that re-render unnecessarily on interaction.
  • Measure INP in production. Instrument the web-vitals library in your app and send real INP data to your analytics platform.

How to monitor Core Web Vitals ongoing

Fixing your CWV once is not enough. Every new plugin, JavaScript library, or image upload is a potential regression.

  • Google Search Console — check weekly. The Core Web Vitals report shows field data for all your URLs and how scores change over time.
  • PageSpeed Insights — run after every deployment. Test your key landing pages after any significant code or content change.
  • web-vitals JavaScript library — real-user monitoring. Captures real CWV data from actual visitors and sends it to Google Analytics or any analytics platform.
  • Lighthouse CI — in your deployment pipeline. Runs Lighthouse on every pull request and blocks merges that cause performance regressions.

When to re-test: After any theme change → After adding/removing plugins or apps → After a hosting migration → After adding new third-party scripts → Quarterly as a standard SEO health check.

Timeline: Google's CrUX data updates monthly. After deploying fixes, expect Search Console to reflect improvements within 28–35 days.

Frequently asked questions

Q1. Do Core Web Vitals directly affect my Google rankings? 

Yes, but they are a tiebreaker — not the primary ranking factor. For competitive keywords where content quality is similar between pages, CWV can be the deciding factor.

Q2. How long until I see improvements in Search Console? 

Google's CrUX data is collected over a rolling 28-day window. Expect improvements to show up in Search Console within 28–35 days of deploying your fixes.

Q3. My Lighthouse score is 90+, but Search Console still shows poor CWV. Why?

Lighthouse uses simulated lab data on a high-end device with a fast connection. Search Console uses real-user data, including older phones and slow mobile connections. The two regularly disagree. Field data is what Google uses — always prioritise fixing that over chasing a lab score.

Q4. Can I pass on desktop and fail on mobile? 

Yes. Google measures desktop and mobile completely separately. Both need to pass to get the full Page Experience benefit. Mobile is almost always harder to fix.

Q5. Is INP harder to fix than FID was? 

Significantly. FID only measured the first interaction on page load. INP measures every interaction across the entire session and uses the worst one. JavaScript-heavy sites — React apps, ecommerce pages with filters, sites with heavy chat widgets — will find INP the hardest to pass.

Summary and next steps

Most sites can move from Poor to Good on all three metrics in 4–8 weeks of focused work. Here is the approach:

  1. Diagnose first. Open Search Console and PageSpeed Insights. Find which metric is failing on which pages.
  2. Fix LCP first. For most sites, this is the biggest issue. A TTFB fix and hero image preload alone often move LCP from Poor to Good.
  3. Then fix CLS. Usually, image dimensions and font loading fixes.
  4. Then fix INP. JavaScript auditing and third-party script reduction.
  5. Monitor monthly. Check Search Console weekly and run PageSpeed Insights after every major deployment.

Every day your Core Web Vitals are failing is a day a competitor with a faster page has the edge. The fixes are well-documented, the tools are free, and the improvements compound over time.

Author Image

Hardeep Singh

Hardeep Singh is a tech and money-blogging enthusiast, sharing guides on earning apps, affiliate programs, online business tips, AI tools, SEO, and blogging tutorials. About Author.

Previous Post