How to Fix Core Web Vitals Issues: LCP, INP and CLS

By the Mayab Media Team · Level: Advanced · Time: 2 hours

Search Console says your URLs are Poor or Need improvement under Core Web Vitals. You run PageSpeed Insights and get a score that bounces around between tests. The report names a metric, like "INP issue: longer than 200ms", but doesn't tell you what to change.

Core Web Vitals are three measurements from real Chrome users. Largest Contentful Paint (LCP) measures loading. Interaction to Next Paint (INP) measures how quickly the page responds to clicks, taps and key presses. Cumulative Layout Shift (CLS) measures how much the layout jumps. INP replaced First Input Delay (FID) as a Core Web Vital in March 2024, so older advice about FID no longer applies.

Fixing them is a loop. You find which metric fails and on which page template, you find the specific cause, you ship a fix, and you wait for field data to catch up. This guide follows that loop with the tools Google gives you for free.

Quick answer

  1. In Search Console, open Core Web Vitals, start with Mobile, and note which metric fails for which URL group.
  2. Run an example URL in PageSpeed Insights. Trust the field data section for pass or fail, and use the lab section to find causes.
  3. For LCP: make the main image or text load early, never lazy-load it, and cut server time and render-blocking files.
  4. For INP: find the slow interaction, break up long JavaScript tasks, and trim third-party scripts.
  5. For CLS: give images, embeds and ads reserved space, and stop injecting content above what people are reading.
  6. Deploy to the whole template, then click Validate fix in Search Console and allow the 28-day window to pass.

Before you start

Here's what you need:

  • Access to the Search Console property (any permission level can view the report; validation needs Owner or Full user).
  • Google Chrome with DevTools for testing.
  • Someone who can change templates, image settings, scripts and the server or CDN configuration.
  • A staging site or a way to roll back. Performance changes can break layouts or tracking.

Know the thresholds before you start. Google measures each metric at the 75th percentile of page visits, separately for mobile and desktop.

Metric Good Needs improvement Poor
LCP 2.5 s or less Up to 4 s Over 4 s
INP 200 ms or less Up to 500 ms Over 500 ms
CLS 0.1 or less Up to 0.25 Over 0.25

A page passes Core Web Vitals only when all three are good at the 75th percentile.

Step 1: Find the failing metric and template in Search Console

In Search Console, open Experience > Core Web Vitals. You'll see two charts: Mobile and Desktop. Click Open report next to Mobile first. Most sites have more mobile traffic and slower mobile results.

search.google.com/search-console/core-web-vitalsSearch ConsoleEexample.comOverviewPerformanceURL inspectionINDEXINGPagesEXPERIENCECore Web VitalsHTTPSCore Web VitalsMobilePoor URLs312Need improvement540Good URLs1,906IssueValidationURLsINP issue: longer than 200ms (mobile)Not started540LCP issue: longer than 4s (mobile)Not started312CLS issue: more than 0.1 (mobile)Not started1181
Figure 1. Each issue row names the metric and the threshold it fails. Click a row to see URL groups. Illustration of the screen. Labels can differ slightly in your account.
  1. Click an issue row to see the URL groups behind it.

The report groups URLs that behave alike, usually pages built on the same template. Each group takes the status of its worst metric. Click a group to see an example URL and the group's value for that metric.

Write down three things for each issue:

  • The metric (LCP, INP or CLS).
  • The template behind the group, such as blog posts, product pages or the homepage.
  • One example URL.

If a page doesn't show up at all, it probably doesn't have enough real-user data. Search Console only reports URLs and groups with enough Chrome traffic, and only indexed URLs.

Step 2: Read PageSpeed Insights the right way

Go to PageSpeed Insights (pagespeed.web.dev), paste the example URL and click Analyze. The results have two very different parts.

pagespeed.web.dev/analysis/https-example-comPageSpeed InsightsDiscover what your real users are experiencingMobileDesktopThis URLOrigin!Core Web Vitals Assessment: FailedLCP4.6 sINP180 msCLS0.04Diagnose performance issuesPerformance52LCP (lab)6.1 sTotal Blocking Time480 ms12
Figure 2. Top: real-user field data that decides pass or fail. Bottom: a single lab test used to find causes. Illustration of the screen. Labels can differ slightly in your account.
  1. Field data. This is the Chrome UX Report: real visits over the last 28 days. It drives the pass or fail result and matches what Search Console uses.
  2. Lab data. This is one simulated Lighthouse load. Use it to find causes, not to judge success.

A few rules that save hours:

  • The Performance score is not a Core Web Vital. A page can score 60 and still pass, or score 90 and fail on INP.
  • Lab tests can't measure INP, because nobody clicks anything. Total Blocking Time is the closest lab hint.
  • If the This URL tab has no data, switch to Origin to see the whole site.
  • Field data moves slowly. It's a 28-day rolling window, so a fix shipped today shows its full effect about four weeks later.

Scroll down to the diagnostics. In current versions of Lighthouse these are listed as Insights, with names like LCP breakdown, LCP request discovery, Render-blocking requests and Layout shift culprits. Names can change between versions, but each one points at a specific cause.

Step 3: Fix LCP (slow loading)

First, find the LCP element. In PageSpeed Insights, open the LCP breakdown insight (older reports call it "Largest Contentful Paint element"). It's usually a hero image, a large heading or a background image.

The LCP time splits into four parts. Each part has a different fix.

Part What it means Usual fix
Time to First Byte Server is slow to send the HTML Caching, CDN, fewer redirects, faster hosting
Resource load delay The browser finds the image late Put it in the HTML, preload it, add fetchpriority
Resource load duration The image file is big Resize, compress, AVIF or WebP
Element render delay Something blocks painting Fewer render-blocking CSS and JS files

Make the LCP image load early

The most common problem is a hero image that the browser discovers too late. That happens when it's set as a CSS background, inserted by JavaScript, or lazy-loaded.

<!-- Good: in the HTML, high priority, not lazy -->
<img src="/img/hero-1200.avif"
     width="1200" height="630"
     fetchpriority="high"
     alt="Team working on a website audit">

<!-- If the image is a CSS background, preload it in the <head> -->
<link rel="preload" as="image" href="/img/hero-1200.avif" fetchpriority="high">

Never put loading="lazy" on the LCP image. Many themes and plugins lazy-load every image by default, including the first one. Exclude the hero from lazy loading. Use fetchpriority="high" on one or two images at most.

Shrink the file

Serve an image close to the size it displays at. A 3000-pixel photo shown at 800 pixels wastes most of the download. Use srcset so phones get a smaller file, and use AVIF or WebP.

Cut server time

If Document request latency or TTFB is large, look at the server before anything else:

  • Turn on full-page caching or edge caching at your CDN.
  • Remove redirect hops. Link straight to the final URL.
  • Avoid query strings that bypass the cache, such as unique tracking parameters on internal links.

Remove render blockers

Large CSS files and synchronous scripts in the <head> delay the first paint. Defer scripts that aren't needed to render the top of the page. Remove unused CSS. Move tag managers and chat widgets so they don't block rendering. If you load tags through Google Tag Manager, our guide to installing Google Tag Manager covers the standard async snippet.

Step 4: Fix INP (slow response to clicks and taps)

INP looks at the interactions on a page and reports one of the slowest. Each interaction has three phases:

  1. Input delay: the browser is busy with other work when the user taps.
  2. Processing duration: your event handlers take long to run.
  3. Presentation delay: the browser takes long to paint the result.

Find the slow interaction

Open the page in Chrome. Open DevTools, then the Performance panel. Recent Chrome versions show live LCP, CLS and INP values there as you use the page. Click the menu, open accordions, add to cart, submit forms. Watch which interaction pushes INP up.

example.com/product/blue-widgetChrome DevToolsPerformanceLive metrics from your local sessionLCP2.1 sCLS0.02INP420 msInteractionElementDurationpointerbutton.add-to-cart420 mskeyboardinput#search96 mspointernav .menu-toggle64 msRecordRecord and reload12
Figure 3. Live metrics show which interaction is slow. Record a trace while repeating it to see the long task. Illustration of the screen. Labels can differ slightly in your account.
  1. Live INP for your session. It turns red when it goes past 500 ms.
  2. The interaction log shows which element was slow.

Then click Record, repeat the slow interaction, and stop. In the trace, long tasks are marked with a red corner. Expand them to see which script ran. The INP breakdown insight shows the three phases for that interaction.

For field data on real users, the open-source web-vitals JavaScript library can report the slow element and phase to your analytics. That tells you which interactions hurt on real phones, not just on your laptop.

Common INP fixes

  • Break up long tasks. If a click handler does a lot of work, do the visible update first and yield to the main thread before the rest.
  • Defer non-urgent work. Analytics events, logging and recalculations can run after the next paint.
  • Trim third-party scripts. Chat widgets, heatmaps, A/B testing tools and some tag setups run heavy code on every interaction. Check the Third parties insight. Remove tags you no longer use.
  • Keep the DOM small. Very large pages make every style and layout update slower. The Optimize DOM size insight flags this.
  • Avoid forced layout. Reading sizes (like offsetHeight) right after changing styles forces the browser to recalculate layout. The Forced reflow insight points to the code.
// Show the result first, then yield before the heavy work
button.addEventListener('click', () => {
  showSpinner();                 // visible update right away
  setTimeout(() => {
    recalculateCart();           // heavy work runs after the next paint
    sendAnalyticsEvent();
  }, 0);
});

In browsers that support it, scheduler.yield() does the same job with less delay. Check support before you rely on it, and keep a setTimeout fallback.

Step 5: Fix CLS (layout jumps)

Open the Layout shift culprits insight in PageSpeed Insights or in a DevTools trace. It lists the elements that moved and, often, the reason: an image without size, a web font, or injected content.

pagespeed.web.dev/analysis/https-example-comPageSpeed InsightsInsightsDiagnose performance issuesLayout shift culpritsTotal CLS 0.27 from 3 shiftsLCP breakdownElement render delay is the largest partRender-blocking requests4 files delay the first paintElementShiftLikely causediv.promo-banner0.18Injected contentimg.hero0.06Unsized imageh10.03Web font12
Figure 4. Layout shift culprits names the elements that moved and the likely cause. Illustration of the screen. Labels can differ slightly in your account.
  1. Open Layout shift culprits to see where CLS comes from.
  2. Fix the largest shift first. One banner often accounts for most of the score.

Common CLS fixes

Size every image and video. Add width and height attributes. The browser uses them to reserve the right space, even with responsive CSS.

img { max-width: 100%; height: auto; }   /* keeps the ratio from width/height */
.video-embed { aspect-ratio: 16 / 9; }   /* reserve space for iframes */
.ad-slot { min-height: 250px; }          /* reserve the most likely ad size */

Reserve space for late content. Cookie banners, promo bars, ads and "related products" blocks often load after the page renders and push content down. Give them a fixed slot with min-height, or show them as an overlay that doesn't move the page.

Tame web fonts. When a web font swaps in, text can change size and shift lines. Preload the main font file, choose a close fallback font, and consider font-display: optional or metric overrides like size-adjust so the swap doesn't move text.

Animate with transform. Animating top, left, height or margin moves other elements. Use transform instead.

Check the back/forward cache. Pages restored from the bfcache don't repeat their load shifts. Avoid things that make pages ineligible, such as unload handlers.

Lab tools only see shifts during load. If your field CLS is much worse than the lab value, the shifts happen later: while scrolling, after a click, or when lazy content loads. Reproduce that flow in DevTools with the live metrics open.

Still not working? Common causes

Symptom Likely cause Fix
Lab score improved but Search Console didn't move Field data is a 28-day rolling window Wait about four weeks after the full deploy before judging
PageSpeed score changes every run Lab tests vary with network and server load Run three times and compare the median; rely on field data
LCP fine on desktop, poor on mobile Large images, slow CPU, heavy JavaScript on phones Serve smaller images with srcset and cut JavaScript on mobile
LCP image still slow after preload It's lazy-loaded or hidden in a slider Remove lazy loading; make the first slide a real img tag
INP poor but lab looks clean Lab tests don't interact with the page Use DevTools live metrics and test real clicks on a mid-range phone
INP got worse after adding tags New third-party scripts run on every click Remove unused tags, delay non-essential ones, review Third parties
CLS only bad in the field Shifts after load (ads, infinite scroll, banners) Reserve space and reproduce while scrolling
A URL group is missing from the report Not enough Chrome traffic for that group Use the Origin view in PageSpeed Insights or your own RUM data
Validation failed Some URLs in the group still fail Fix the template everywhere, including variants like AMP or filtered pages

Caching plugins that cause new problems

Optimization plugins can help, but some settings backfire. Combining all JavaScript into one file can create a single long task that hurts INP. Lazy-loading every image hurts LCP. Delaying all scripts until interaction can break forms and tracking. Turn options on one at a time, test, and keep notes.

Hosting limits

If TTFB is high even on a simple cached page, the server may be the bottleneck. A CDN with page caching often helps more than any front-end tweak. If you can't cache (for example, logged-in or cart pages), work with your host or developer on database and backend speed.

How to confirm it's fixed

Check right after deployment:

  1. Run the example URL in PageSpeed Insights again. The lab LCP, TBT and CLS values and the relevant insights should improve.
  2. In DevTools live metrics, repeat the slow interactions. INP should stay under 200 ms on a throttled CPU.
  3. Use URL Inspection > Test live URL in Search Console on a couple of pages to make sure Google still renders them correctly after the changes.

Then start validation in Search Console. Open the issue in the Core Web Vitals report and click Validate fix (the help center calls this "Start tracking"). Search Console monitors the affected URLs for 28 days. If the issue doesn't appear on any URL in that window, it's marked as fixed.

In PageSpeed Insights, the field data section updates as the 28-day window rolls. Expect a gradual change rather than a jump.

Faster pages also help discovery and crawling. If new pages are slow to appear in Google, see how to get Google to index your site.

FAQ

Do Core Web Vitals affect rankings?

They are part of Google's page experience signals. Good scores won't save weak content, and poor scores rarely sink a great page on their own. Treat them as a user experience fix that also removes a ranking risk.

Why does PageSpeed Insights show "No data" for field data?

The URL doesn't have enough Chrome visits in the Chrome UX Report. Switch to Origin for the site-wide view, or collect your own real-user data with the web-vitals library.

Is FID still measured?

No. INP replaced FID as a Core Web Vital in March 2024. Remove FID from your reports and dashboards.

What should I fix first?

Start with the metric that fails on the template with the most traffic, usually on mobile. One template fix often moves hundreds of URLs at once.

Does structured data or schema affect Core Web Vitals?

Not in a meaningful way. A JSON-LD block is small and doesn't render. If you're adding it, see how to add schema markup and test it.

Stuck on this one? We fix these for clients every week. Book a free audit

Sources

Previous
Previous

How to Add Schema Markup (JSON-LD) and Test It

Next
Next

How to Fix Soft 404 Errors in Google Search Console