DEV Community

Cover image for Core Web Vitals in Practice: Fix LCP, INP, and CLS Without Guessing
Search Engine Basics
Search Engine Basics

Posted on

Core Web Vitals in Practice: Fix LCP, INP, and CLS Without Guessing

Core Web Vitals is one of the most searched topics in technical SEO, and one of the most misunderstood. Teams run a Lighthouse test, see a red score, and start optimizing whatever the report lists first. That is backwards. The scores that matter are not the ones from your laptop. They are the ones from your real visitors, collected over 28 days, judged at the 75th percentile.

I have debugged these metrics on content sites, dashboards, and e-commerce builds. This is the order of work that actually moves them.

The three metrics and what "good" means

Google keeps the set deliberately small:

  • LCP (Largest Contentful Paint): how fast the main content appears. Good is 2.5 seconds or less.
  • INP (Interaction to Next Paint): how fast the page responds when a user clicks, taps, or types. Good is 200 milliseconds or less. INP replaced FID in March 2024 because it measures the full interaction, not just the first delay.
  • CLS (Cumulative Layout Shift): how much the layout jumps around while loading. Good is 0.1 or less.

To pass, at least 75% of real visits must land in the "good" range for all three. One failing metric fails the assessment. If you want the full reference in one place, this Core Web Vitals guide covers each metric's definition and measurement in depth. The rest of this article is about fixing them.

Field data beats lab data, every time

Lighthouse and PageSpeed's top score are lab data: one simulated run, on one device, on one connection. Useful for debugging, useless as a verdict. Field data (the Chrome User Experience Report, or your own analytics) is what Google actually uses for the page experience signal.

The gap between the two surprises people. A page can score 95 in the lab and fail in the field because real visitors arrive on mid-range Android phones, on slow networks, with caches in unknown states. Always start from field data, find the templates that fail, then reproduce them in the lab to debug. Optimizing in the other direction burns weeks.

LCP: find the element before you fix anything

LCP fails more than the other two combined, and the first step is embarrassingly simple: identify which element is the LCP element on your failing templates. It is usually the hero image or the headline block, and the fix depends entirely on which one it is.

The usual culprits, in the order I check them:

  • Slow server response. If TTFB is poor, nothing downstream can save LCP. Cache the page, fix the backend, or put a CDN in front of it.
  • Render-blocking resources. CSS and synchronous scripts in the head delay first paint, and LCP waits behind them.
  • The hero image itself. Uncompressed, wrongly sized, lazy-loaded by mistake, or discovered late because it is set as a CSS background. Preload the actual LCP image and never lazy-load it.
  • Web fonts. A headline waiting on a font swap paints late. Preload the critical font or use font-display properly.

Performance work runs on budgets, and the budget mindset matters more than any single trick. Serving teams in AI products work the same way, where a strict inference latency budget decides whether a feature feels instant or broken. Your LCP budget deserves the same discipline: a number, an owner, and a check that runs on every release.

Fix LCP in This Order

INP: the metric your JavaScript is failing

INP is where modern front-ends struggle. Every interaction is measured in three parts: input delay (waiting for the main thread), processing time (your event handlers), and presentation delay (rendering the result). Long tasks block all three.

Practical fixes that consistently help:

  • Break up long tasks with yielding (scheduler.yield or setTimeout splits) so input can interleave.
  • Audit third-party scripts. Tag managers and chat widgets are frequent INP killers, and nobody owns them.
  • Keep the DOM smaller on interactive pages. Style and layout costs scale with node count.
  • Debounce input handlers, and move heavy computation off the critical interaction path.

Measure INP per interaction type in the field. The search box, the menu, and the checkout button will tell you different stories.

CLS: stop the page from moving

Layout shift is the most fixable metric because its causes are mechanical:

  • Images and videos without width and height attributes (or an aspect-ratio box) reserve no space.
  • Ads, embeds, and iframes injected into space that was never reserved for them.
  • Content pushed in late: cookie banners, promo bars, and client-side rendered blocks appearing above existing content.
  • Web fonts swapping and reflowing text.

Reserve space for everything that loads late. If an element cannot have a reserved box, load it below the fold or behind a user action. Most pages can reach near-zero CLS with a day of disciplined fixes, and it stays fixed because the causes do not drift the way performance does.

4 CLS Traps (All Fixable)

The workflow that keeps scores green

Passing once is not the goal. Scores decay as pages gain features, images, and third-party weight. The sites that stay green treat Core Web Vitals as a release gate: field data reviewed monthly, a budget per template, and a rule that a regression gets a ticket like any other bug.

Start with the field data, fix the failing template, and verify at the 75th percentile over the next 28-day window. That loop, repeated, is the entire discipline.

Top comments (0)