Core Web Vitals Debugging Guide
Debug and optimize LCP, INP, and CLS — Google's Core Web Vitals. Covers Chrome DevTools techniques, the web-vitals library, real user monitoring, and the most impactful fixes.
Core Web Vitals Quick Reference
| Metric | Measures | Good | Poor |
|---|---|---|---|
| LCP | Largest element renders | < 2.5s | > 4s |
| INP | Interaction responsiveness | < 200ms | > 500ms |
| CLS | Layout stability | < 0.1 | > 0.25 |
| FCP | First content paints | < 1.8s | > 3s |
| TTFB | Server response time | < 800ms | > 1.8s |
Measuring Vitals with the web-vitals Library
npm install web-vitals
// vitals.ts — send metrics to your analytics endpoint
import { onLCP, onINP, onCLS, onFCP, onTTFB } from 'web-vitals';
function sendToAnalytics(metric: object) {
// Send to your backend, Google Analytics, or Datadog
navigator.sendBeacon('/api/vitals', JSON.stringify(metric));
}
onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
onFCP(sendToAnalytics);
onTTFB(sendToAnalytics);
// Next.js: add to app/layout.tsx or pages/_app.tsx
// export { reportWebVitals } from 'next/dist/pages/_app'
// function reportWebVitals(metric) { sendToAnalytics(metric) } LCP Optimization Techniques
<!-- 1. Preload the LCP image -->
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high">
<!-- 2. Mark the LCP image with fetchpriority -->
<img src="/hero.webp" fetchpriority="high" loading="eager" alt="Hero"
width="1200" height="600">
<!-- 3. Avoid lazy-loading above-the-fold images -->
<!-- BAD: -->
<img src="/hero.webp" loading="lazy"> <!-- NEVER lazy-load LCP -->
<!-- GOOD: -->
<img src="/hero.webp" loading="eager" fetchpriority="high"> // Next.js Image component — automatically adds fetchpriority="high"
import Image from 'next/image';
<Image
src="/hero.webp"
priority // ← This is the key prop for LCP images
width={1200}
height={600}
alt="Hero"
/> INP Optimization — Reducing Long Tasks
// Identify long tasks in Chrome DevTools:
// Performance tab → record → look for red triangles on tasks > 50ms
// Pattern 1: Break up long synchronous work with scheduler.yield()
async function processLargeList(items: Item[]) {
for (let i = 0; i < items.length; i++) {
processItem(items[i]);
// Yield every 50 items to avoid blocking the main thread
if (i % 50 === 0) {
await scheduler.yield(); // releases main thread briefly
}
}
}
// Pattern 2: Defer non-critical work
// BAD: blocking third-party script in <head>
<script src="https://analytics.example.com/script.js"></script>
// GOOD: defer + async
<script src="https://analytics.example.com/script.js" defer async></script>
// Pattern 3: Use web workers for CPU-heavy computation
const worker = new Worker('/workers/heavy-computation.js');
worker.postMessage({ data: largeDataset });
worker.onmessage = (e) => setResult(e.data.result); CLS Fixes
<!-- Fix 1: Always specify image dimensions -->
<!-- BAD: no dimensions = layout shift when image loads -->
<img src="/photo.jpg" alt="Photo">
<!-- GOOD: browser reserves space before image loads -->
<img src="/photo.jpg" alt="Photo" width="800" height="600">
<!-- Fix 2: Reserve space for ads and embeds -->
<div style="min-height: 250px">
<!-- ad loads here without shifting content below -->
<ins class="adsbygoogle" style="display:block" ...></ins>
</div>
/* Fix 3: Font display swap to prevent FOUT layout shift */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2');
font-display: optional; /* never causes layout shift */
}
/* Fix 4: Aspect ratio container for responsive media */
.video-wrapper {
aspect-ratio: 16 / 9; /* reserves correct space before video loads */
} DevTools Workflow
- Performance tab → Record page load → look for LCP marker, long tasks (red triangles), layout shifts
- Rendering panel (⋮ menu → More tools) → Enable "Layout Shift Regions" to see shifting elements highlighted in teal
- Network throttling → Set to "Slow 3G" or "Fast 3G" to simulate real mobile conditions
- Web Vitals Chrome extension → Overlays LCP element, INP interactions, and CLS contributors in real time
- PageSpeed Insights → Combines Lighthouse lab data with real CrUX field data for your URL
Frequently Asked Questions
What are Core Web Vitals and why do they affect SEO?▼
Core Web Vitals are Google's standardized set of user experience metrics used as ranking signals: LCP (Largest Contentful Paint) measures loading speed, INP (Interaction to Next Paint, replaced FID in 2024) measures responsiveness to user input, and CLS (Cumulative Layout Shift) measures visual stability. Sites with poor Core Web Vitals can be demoted in search rankings. Google uses field data from Chrome User Experience Report (CrUX) — real user measurements — not lab data from Lighthouse.
What is a good LCP score and how do I improve it?▼
Good LCP: under 2.5 seconds. Needs improvement: 2.5-4 seconds. Poor: over 4 seconds. The main LCP element is usually a hero image, above-the-fold heading, or large text block. To improve LCP: add fetchpriority='high' to the LCP image, preload critical images with <link rel=preload>, serve images in WebP/AVIF format, use a CDN to reduce server response time, and eliminate render-blocking resources (unused CSS/JS) that delay LCP element rendering.
How do I diagnose and fix Cumulative Layout Shift (CLS)?▼
CLS occurs when elements shift position after the page loads. The most common causes are: images without explicit width/height attributes (reserve space by always setting dimensions), ads and embeds that inject content above existing elements, web fonts causing a Flash of Unstyled Text (FOUT) that shifts layout. To debug: open Chrome DevTools > Performance > record a page load and look for Layout Shift entries. Use the Layout Instability API or the Web Vitals Chrome extension to identify which elements shift.
What is INP and how is it different from FID?▼
INP (Interaction to Next Paint) replaced FID (First Input Delay) as a Core Web Vital in March 2024. FID measured only the delay before the browser starts processing the first user interaction. INP measures the full duration from user input to the next visual frame across all interactions during the page lifetime — it's a much more complete measure of responsiveness. Good INP: under 200ms. Poor INP: over 500ms. Long tasks on the main thread are the primary INP culprit.
How do I measure real user Core Web Vitals (field data)?▼
Use the web-vitals JavaScript library (npm install web-vitals) to collect metrics from real users and send them to your analytics. Call onLCP, onINP, onCLS, onFCP, onTTFB with a callback that sends the metric to your endpoint. Google Search Console shows aggregated field data from CrUX. PageSpeed Insights shows both lab (Lighthouse) and field data. Field data typically differs from Lighthouse because it reflects real devices, real networks, and real user behavior.
Why does my Lighthouse score look good but field data shows poor Core Web Vitals?▼
Lab data (Lighthouse) simulates a mid-tier device with throttled network in a controlled environment. Field data comes from real users on real devices across all connection types. Common gaps: your users are on slow mobile devices (Lighthouse uses a Moto G4 simulation), your JS bundle is large and blocks interaction on low-end hardware, third-party scripts (ads, chat widgets, analytics) add significant weight in production but may be absent in local testing, or your CDN cache is warm in tests but cold for new users.
Related Products
on GumroadDeveloper Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad →AI Prompt Engineering Toolkit
58 structured prompt templates for Claude, ChatGPT, and Gemini — organized by use case. Code Review, Debugging, Documentation, Architecture, and 10 model-specific tips. Stop writing prompts from scratch.
Buy on Gumroad →Developer Cheat Sheet Bundle
10 print-ready cheat sheets for the tools developers use every day: Git, Docker, Linux CLI, SQL, Regex, HTTP Status codes, VS Code shortcuts, Bash scripting, jq/JSON, and Markdown.
Buy on Gumroad →You Might Also Need
Web Vitals Budget Planner
Plan Core Web Vitals budgets. Set LCP/CLS/INP targets for e-commerce, blog, SaaS, or custom pages. Get resource size limits, JS execution budget, and third-party script allowances.
Open free tool →
Web Performance Checklist
Interactive web performance checklist covering images, fonts, JavaScript, CSS, caching, and server. Check off items to track your score out of 100 and export as Markdown.
Open free tool →
Web Vitals Analyzer
Analyze and score Core Web Vitals. Enter LCP, INP, CLS, TTFB, and FCP values to get good/needs improvement/poor ratings with optimization tips.
Open free tool →
More Free Tools
Related Articles
Web Vitals Optimization: Achieve Core Web Vitals Score 90+ in 2026
Step-by-step guide to achieving Core Web Vitals score of 90+ in 2026. Covers LCP, INP, CLS optimization techniques with code examples, measurement tools, and before/after benchmarks.
Web Performance and Core Web Vitals 2026: Complete Optimization Guide
Complete guide to Core Web Vitals optimization in 2026. Covers LCP, INP, CLS, TTFB optimization with real code examples. Includes Next.js, React, Vite, Cloudflare Workers, and backend optimization strategies for achieving 90+ Lighthouse scores.
Web Performance 2026: INP, Core Web Vitals & Lighthouse CI
Master web performance in 2026: INP replacing FID, LCP and CLS optimization, Lighthouse CI in GitHub Actions, RUM with web-vitals.js, and setting performance budgets to keep your site fast.
Web Performance Optimization: Improve Your Core Web Vitals in 15 Steps
15 actionable web performance optimization techniques to improve LCP, CLS, and INP (Core Web Vitals). Real code examples, measurement tools, and before/after results.
JavaScript Bundle Size Optimization: From 2MB to 200KB — A Practical Guide
Practical techniques to reduce JavaScript bundle size from megabytes to kilobytes. Covers tree shaking, code splitting, dynamic imports, bundle analysis, and tools that actually work in 2026.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- ⚡ AI Code Review, Doc Generator & SQL Builder
- ⚡ All premium templates & early access
- ⚡ Member discounts on Gumroad products
$9/mo after trial · Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.
MIT licensed · Instant download · No subscription
See what's included → Browse all deals →