
As someone who's spent countless hours diagnosing performance bottlenecks at 3 AM, I can tell you that core web vitals issues are some of the most frustrating problems you'll encounter as a DevOps engineer. One minute your site is performing beautifully, the next you're staring at red metrics in Google Search Console wondering what went wrong.
In my experience working with teams across different industries, I've seen how seemingly minor changes can tank your Core Web Vitals overnight. A new third-party script here, an unoptimized image there, and suddenly your LCP worsens. The business impact is immediate and measurable.
Understanding Core Web Vitals Issues in 2026
What Are Core Web Vitals and Why They Matter
Core Web Vitals are Google's three key metrics that measure real user experience: Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). Google says strong Core Web Vitals align with what its core ranking systems seek to reward, and they decide how fast and stable the page feels to visitors.
The "good" thresholds are: LCP ≤2.5 seconds, INP ≤200ms, and CLS ≤0.1. The LCP and CLS thresholds haven't changed since they were introduced. INP replaced First Input Delay (FID) in March 2024. What matters is that 75% of your real users must experience "good" performance on these metrics. Google uses Chrome User Experience Report (CrUX) data to evaluate your site at the 75th percentile.
I've worked with e-commerce sites where fixing core web vitals issues led to immediate business improvements. When Vodafone improved its LCP by 31% in an A/B test, sales rose 8% and its lead-to-visit rate rose 15% (web.dev case study).
How Core Web Vitals Are Measured
Google documents one set of thresholds for every site, with three ranges per metric:
| Metric | Good | Needs improvement | Poor |
|---|---|---|---|
| LCP | ≤2.5 s | ≤4 s | >4 s |
| INP | ≤200 ms | ≤500 ms | >500 ms |
| CLS | ≤0.1 | ≤0.25 | >0.25 |
Each metric is assessed at the 75th percentile of page loads: 75% of visits must meet the "good" value. Mobile and desktop are assessed separately, and in Search Console a group of URLs takes the status of its worst metric. A page that passes on desktop can still fail on mobile.
Business Impact: Real Performance Data
The clearest public number comes from Vodafone. In an A/B test described on web.dev, half of the traffic from paid channels went to a landing page with Web Vitals optimizations and half to the baseline page. The optimized page had a 31% better LCP (5.7 seconds against 8.3 seconds), 8% more sales, a 15% higher lead-to-visit rate and an 11% higher cart-to-visit rate. The changes were moving a widget's rendering from the client to the server, rendering critical HTML on the server, and optimizing images, including resizing the hero image. That is one company's result, so measure your own.
I've worked with teams on systematic LCP, INP and CLS optimization. The key is treating this as an engineering problem, not just a marketing concern.
How to Identify Core Web Vitals Issues
Essential Detection Tools and Methods
The most effective approach combines multiple monitoring tools to capture both real user data and controlled testing environments. Start with Google Search Console for authoritative field data, then layer in additional tools for deeper insights.
Here's my recommended detection toolkit:
- Google Search Console - Your primary source for SEO-impacting field data
- PageSpeed Insights - Combines lab and field data with actionable recommendations
- WebPageTest - Detailed performance waterfalls for debugging
- Real User Monitoring (RUM) - Continuous monitoring with business metric correlation
I always tell teams to avoid relying on a single tool. Each provides different perspectives on your performance issues. Lab data gives you consistent, controllable conditions for debugging, while field data shows what real users actually experience.
Reading Google Search Console Data
Google Search Console is the most direct view of your core web vitals issues because its Core Web Vitals report is built from CrUX field data, the same real-user data Google publishes. Navigate to the "Core Web Vitals" report to see your site's performance broken down by mobile and desktop.
The report groups URLs into three categories: Good (green), Needs Improvement (yellow), and Poor (red). Focus on the "Poor" URLs first. The report shows which specific metric is failing and provides example URLs for investigation.
Pay attention to the trend data. I've seen sites where developers thought they'd fixed issues, but the 28-day rolling average in Search Console told a different story. The report covers the last 28 days of page requests, and when you click Start Tracking after a fix, Search Console runs a 28-day monitoring session. Expect to wait about four weeks before a fix is fully reflected.
Field vs Lab Data: When to Use Each
Field data represents real user experiences across diverse devices and network conditions, while lab data provides controlled, reproducible testing environments. Both are essential for comprehensive core web vitals troubleshooting.
Use field data (CrUX, Google Search Console) for:
- Understanding actual user impact
- Prioritizing optimization efforts
- Seeing the data Google's Core Web Vitals report uses
- Identifying device-specific issues
Use lab data (PageSpeed Insights, WebPageTest) for:
- Debugging specific performance bottlenecks
- Testing optimization hypotheses
- Consistent before/after comparisons
- Detailed performance waterfall analysis
In my experience, teams often make the mistake of optimizing only for lab scores. While lab improvements usually correlate with field improvements, real users face network variability, device limitations, and usage patterns that lab tests can't replicate.
Setting Up Continuous Monitoring
Continuous monitoring is crucial because core web vitals issues can emerge suddenly. A new deploy, third-party script update, or CDN configuration change can instantly degrade performance.
I recommend implementing alerts for:
- Core Web Vitals threshold breaches (>2.5s LCP, >200ms INP, >0.1 CLS)
- Performance regression detection (>20% degradation week-over-week)
- Critical page failures (homepage, checkout, key landing pages)
- Mobile vs desktop performance gaps
Tools like SpeedCurve, New Relic, and Sentry can send alerts. Set up Slack or email notifications so your team is notified when a threshold is crossed. After each deploy, compare the metrics with the previous week's.
Diagnosing Largest Contentful Paint (LCP) Problems
Common LCP Bottlenecks and Root Causes
LCP is the hardest Core Web Vitals metric to pass on mobile: in 2025, 62% of mobile sites had a good LCP, against 77% for INP and 81% for CLS (HTTP Archive Web Almanac 2025). The Largest Contentful Paint measures when the largest visible element finishes loading, typically an image, video, or text block.
The most common LCP bottlenecks I encounter are:
- Slow server response times (TTFB): a slow first byte delays everything that follows
- Unoptimized images - Large file sizes and poor compression
- Render-blocking resources - CSS and JavaScript that delays page rendering
- Inefficient loading sequences - Critical resources loaded too late
When diagnosing LCP problems, start by identifying the LCP element using Chrome DevTools. Open the Performance panel, record a page load, and look for the "LCP" marker. This shows you exactly which element is causing the delay.
TTFB Impact on LCP Performance
Time to First Byte (TTFB) has an outsized impact on LCP because the browser can't start rendering content until it receives the initial HTML response. web.dev's rough guide is that a TTFB of 0.8 seconds or less is good and above 1.8 seconds is poor. TTFB is not a Core Web Vital itself, but it feeds LCP: web.dev suggests that about 40% of a good LCP should be spent on TTFB, and that this is a guideline, not a rule. Focus on:
- Database query optimization
- Server-side caching implementation
- CDN configuration and edge caching
- Application performance profiling
Use WebPageTest to analyze your TTFB across different locations. If you see significant geographic variation, that's a strong indicator that CDN optimization could help. Cloudflare Workers and similar edge computing platforms can reduce TTFB for dynamic content by running it closer to users. Redirects and CDN cache misses are also common causes of a slow first byte. For example, unique URL parameters added for analytics can stop a CDN from serving a cached copy, so check your cache hit ratio.
Image Optimization Strategies
Images are the LCP element on most websites, making optimization critical. The biggest wins come from:
Modern image formats: Use AVIF or WebP instead of JPEG/PNG. AVIF and WebP usually compress better than JPEG or PNG at similar quality, so test both on your own images. Implement format detection and serve the best supported format for each browser.
Proper sizing: Serve images at the exact dimensions needed. A 2000px image displayed at 400px wastes bandwidth and slows LCP. Use responsive images with srcset to deliver appropriate sizes.
Preloading critical images: Add <link rel="preload" as="image" href="hero-image.jpg"> for above-the-fold images. This tells the browser to download the image early, and adding fetchpriority="high" to the LCP <img> helps the browser prioritize it. Use high priority on only one or two images.
Lazy loading exceptions: Don't lazy load the LCP image! I've seen developers accidentally lazy load hero images, which adds avoidable delay before the image even starts loading.
Server and CDN Configuration
Server optimization directly impacts LCP through faster content delivery. Key configurations include:
HTTP/2 and HTTP/3: HTTP/2 multiplexes many requests over one connection. HTTP/3 runs over QUIC (on UDP instead of TCP), which removes head-of-line blocking at the transport layer and can reduce latency.
Compression: Enable Brotli compression for text resources. All modern browsers support it, and it is a common alternative to gzip for text, so check that your server or CDN has it enabled and compare transfer sizes with gzip.
Caching headers: Set appropriate cache headers for static resources. Long-lived caches (1 year for immutable assets) eliminate repeat download overhead.
CDN edge locations: Choose CDNs with extensive global presence. The closer your content is to users, the faster it loads. Check your cache hit ratio when investigating LCP.
Fixing Interaction to Next Paint (INP) Issues
Understanding INP vs Legacy FID Metrics
INP replaced First Input Delay (FID) in 2024 and measures the full interaction chain, not just initial delay. While FID only measured the time until the browser started processing an event, INP tracks the entire duration until visual feedback appears.
This change makes INP more representative of actual user experience. A button click that starts processing immediately but takes 300ms to show visual feedback would have passed FID but fails INP.
INP considers all interactions during a page visit and reports the worst (or near-worst) interaction latency. This means optimizing for INP requires ensuring consistently responsive interactions, not just fast initial responses.
JavaScript Blocking and Main Thread Optimization
The main thread is where JavaScript execution, style calculations, and layout operations occur. When the main thread is blocked, user interactions queue up, causing poor INP scores.
Code splitting is your first defense against main thread blocking. Instead of loading one large JavaScript bundle upfront, split it into smaller chunks that load on demand. Use dynamic imports to defer non-critical functionality:
// Instead of importing everything upfront
import { heavyFeature } from './heavy-module';
// Load on demand
button.addEventListener('click', async () => {
const { heavyFeature } = await import('./heavy-module');
heavyFeature();
});
Task scheduling helps break up long-running operations. Use scheduler.yield() to hand control back to the browser between chunks of work. It is not supported in every browser (web.dev lists Chrome 129, Edge 129 and Firefox 142, not Safari), so fall back to setTimeout:
function yieldToMain() {
if (globalThis.scheduler?.yield) {
return scheduler.yield();
}
// Fall back to yielding with setTimeout.
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}
async function runJobs(jobQueue) {
for (const job of jobQueue) {
job();
await yieldToMain();
}
}
The key is measuring main thread blocking time and systematically reducing it.
Event Handler Performance
Event handlers must complete quickly to maintain good INP scores. The 200ms threshold includes event processing time, layout calculations, and paint operations.
Optimize event handlers by:
Debouncing expensive operations: Don't trigger heavy calculations on every keystroke or scroll event. Use debouncing to batch operations:
const debouncedSearch = debounce((query) => {
performExpensiveSearch(query);
}, 300);
Minimizing DOM manipulation: Batch DOM updates and use DocumentFragment for multiple insertions. Each DOM change can trigger layout recalculation, consuming main thread time.
Async processing: Move heavy computations to Web Workers when possible. This keeps the main thread free for user interaction handling.
Third-Party Script Management
Third-party scripts are notorious INP killers. Analytics, chat widgets, and advertising scripts can block the main thread unpredictably. I've debugged sites where a third-party script caused INP spikes.
Strategies for third-party script optimization:
Lazy loading: Load non-critical third-party scripts after user interaction or page idle time. Use the Intersection Observer API to trigger loading when needed.
Script isolation: Use iframes or Web Workers to isolate third-party code from your main thread. This prevents their blocking behavior from affecting your INP scores.
Performance budgets: Set strict limits on third-party script impact. Monitor their performance contribution and remove scripts that consistently cause problems.
Async and defer attributes: Use async for scripts that don't depend on DOM ready state, defer for scripts that need DOM but aren't critical for initial rendering.
Resolving Cumulative Layout Shift (CLS) Problems
Visual Stability and Layout Shift Detection
CLS measures unexpected layout shifts that occur during page load and user interaction. In 2025, 81% of mobile sites had a good CLS, the best of the three metrics (HTTP Archive Web Almanac 2025). Layout shifts frustrate users and can cause accidental clicks on wrong elements.
CLS is the largest burst of layout shifts in a page's life: shifts less than 1 second apart are grouped into a session window of up to 5 seconds, and the window with the highest total counts. Each shift is scored based on the impact fraction (how much of the viewport was affected) multiplied by the distance fraction (how far elements moved).
Use Chrome DevTools to visualize layout shifts.
The Layout Instability API provides programmatic access to shift data:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('Layout shift:', entry.value, entry.sources);
}
}).observe({entryTypes: ['layout-shift']});
Dynamic Content and Ad Placement
Dynamic content insertion is a common cause of CLS issues. When ads, widgets, or user-generated content loads after initial render, it pushes existing content down the page.
Reserve space for dynamic elements using CSS:
.ad-container {
min-height: 250px; /* Reserve space for banner ad */
background: #f0f0f0; /* Optional placeholder styling */
}
Don't collapse the slot if no ad arrives: web.dev notes that removing reserved space can cause as much CLS as inserting content.
Skeleton screens provide visual placeholders while content loads. They maintain layout stability and improve perceived performance by showing users that content is coming.
Transform animations don't count toward CLS, because composited animations can't move other elements. Use transform: translateY() instead of changing top or margin properties when animating elements into view.
I've worked with news sites on reserving ad space to reduce layout shifts. The key is predicting content dimensions and reserving appropriate space.
Font Loading Optimization
Web font loading can cause significant layout shifts when fallback fonts have different dimensions than the final fonts. The text initially renders in the fallback font, then shifts when the web font loads.
Font-display: swap ensures text remains visible during font load but can cause shifts:
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: swap;
}
Size-adjust property helps match fallback font dimensions to web font dimensions:
@font-face {
font-family: 'Arial Fallback';
src: local('Arial');
size-adjust: 95%; /* Placeholder: calculate from the two fonts' metrics */
}
Preload critical fonts to reduce loading delay:
<link rel="preload" href="critical-font.woff2" as="font" type="font/woff2" crossorigin>
Calculate the size-adjust value (and, if needed, ascent-override and descent-override) from the metrics of the two fonts rather than guessing; 95% above is only a placeholder.
Image and Video Element Sizing
Images and videos without explicit dimensions cause layout shifts when they load and the browser discovers their aspect ratio. Always specify width and height attributes:
<img src="image.jpg" width="400" height="300" alt="Description">
Aspect ratio CSS maintains proportions while allowing responsive sizing:
.responsive-image {
width: 100%;
height: auto;
aspect-ratio: 4/3;
}
Intrinsic sizing for responsive images prevents shifts:
img {
max-width: 100%;
height: auto;
}
For dynamically loaded images, set container dimensions before loading the image. This reserves the necessary space and prevents content reflow.
Advanced Monitoring and Detection Strategies
Real User Monitoring (RUM) Implementation
Real User Monitoring captures actual user experiences across diverse devices, networks, and usage patterns that synthetic testing cannot replicate. RUM provides the field data that Core Web Vitals are assessed on, from your own visitors.
Implement RUM using the web-vitals JavaScript library from the Chrome team. Install it with npm install web-vitals, then report each metric to an endpoint you control. navigator.sendBeacon() is the right way to send it, because it still works while the page is unloading:
import {onCLS, onINP, onLCP} from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
id: metric.id,
page: location.pathname,
});
navigator.sendBeacon('/analytics', body);
}
onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);
Some metrics are reported only after the user interacts with the page, switches tabs or leaves it, and INP is skipped when there is no interaction, so expect fewer INP samples than page views.
Once the data arrives, segment it. Look at the 75th percentile of each metric by page template, by device type (mobile and desktop separately) and by country. That is the same way Google assesses your site, and it shows whether a problem is one template, one third-party script or one slow region.
Where to Start
Open the Core Web Vitals report in Search Console and find your worst group of URLs. Identify the LCP element with Chrome DevTools, check TTFB, and fix the biggest cause first: usually an unoptimized or lazy-loaded hero image, a long main-thread task, or an image or ad without reserved space. Then watch the metrics after each deploy. Visual Sentinel's performance monitoring runs scheduled mobile Lighthouse lab tests that report LCP, CLS, TTFB and Total Blocking Time, and your first check needs no card (the 7-day trial requires one). See the performance monitoring page.
Measure your site speed while you read
Run a free mobile Lighthouse lab check for performance score, LCP, FCP, CLS, TTFB, Total Blocking Time, and Speed Index.
Test site speedCommon questions
What are the current Core Web Vitals thresholds for 2026?
The thresholds are LCP ≤2.5 seconds, INP ≤200ms, and CLS ≤0.1, assessed at the 75th percentile of page loads, separately for mobile and desktop.
How long does it take to see SEO ranking improvements after fixing Core Web Vitals issues?
Google Search Console uses 28-day rolling CrUX data, and its validation runs a 28-day monitoring session, so expect about four weeks before a fix shows in the report. Google does not publish how quickly rankings respond.
Which Core Web Vitals metric is hardest to optimize?
LCP. In 2025, 62% of mobile sites had a good LCP, against 77% for INP and 81% for CLS (HTTP Archive Web Almanac 2025). Server response time, image loading and render-blocking resources are the usual causes.
What percentage of my website pages need to pass Core Web Vitals?
Google publishes no site-wide target. Search Console groups URLs with a similar experience and gives each group a status at the 75th percentile of visits, using its worst metric. The 75% is a share of visits, not of pages. Get your most visited page groups and your key pages (homepage, checkout, landing pages) to Good first.
Should I use lab data or field data for Core Web Vitals optimization?
Use both, but prioritize field data from real users (CrUX, Google Search Console), because that is what Google's report shows. Lab data from tools like PageSpeed Insights helps with debugging and provides consistent testing conditions.
How do Core Web Vitals issues impact business metrics?
It depends on the site. In Vodafone's A/B test, a 31% better LCP came with 8% more sales and a 15% higher lead-to-visit rate (web.dev case study). Measure the effect of your own fixes on your own visitors and business metrics.


