UseToolSuite UseToolSuite
Web Performance 📖 Pillar Guide

Core Web Vitals in 2026: The Complete INP, LCP, and CLS Optimization Playbook

A definitive, practical guide to Core Web Vitals after INP replaced FID. Learn what LCP, INP, and CLS measure, the thresholds that matter, and the concrete techniques to pass each one.

Necmeddin Cunedioglu Necmeddin Cunedioglu 12 min read

Practice what you learn

Image Compressor & WebP Converter

Try it free →

Core Web Vitals in 2026: The Complete INP, LCP, and CLS Optimization Playbook

Core Web Vitals are Google’s attempt to reduce the sprawling, subjective question of “is this page a good experience?” into three measurable numbers. Since their introduction they have become both a ranking signal and an industry-standard way to talk about real-world performance. But the metrics have evolved — most significantly, Interaction to Next Paint (INP) replaced First Input Delay (FID) in March 2024, raising the bar for what “responsive” means. Many teams optimized for the old metric and are now failing the new one without understanding why.

This playbook brings you fully current. It explains what each of the three vitals — LCP, INP, and CLS — actually measures, the thresholds you must hit, and, most importantly, the concrete techniques that move each number. The emphasis is on what works in the field, because Core Web Vitals are judged on real users, not lab simulations.

The three metrics and their thresholds

Core Web Vitals measure three distinct dimensions of experience: how fast the main content loads, how quickly the page responds to input, and how stable the layout is while it loads. Each has a “good” threshold, and the rule that trips people up: you are judged at the 75th percentile of your real users, not the average. If 30% of your visitors have a slow experience, you fail — even if the median is fine.

MetricMeasures”Good” (75th percentile)“Poor”
LCP — Largest Contentful PaintLoading speed≤ 2.5 s> 4.0 s
INP — Interaction to Next PaintResponsiveness≤ 200 ms> 500 ms
CLS — Cumulative Layout ShiftVisual stability≤ 0.1> 0.25

The 75th-percentile rule has a strategic implication: you cannot optimize for your fast users and ignore the slow ones. The visitor on a mid-range Android phone over a congested mobile network is the visitor who decides whether you pass. Test on throttled connections and modest hardware, not just your developer laptop on fiber.

Field data vs lab data: know which one counts

Before optimizing, understand the two kinds of measurement, because conflating them wastes enormous effort.

  • Field data (Real User Monitoring / the Chrome User Experience Report) captures what actual visitors experience on their real devices and networks. This is what Google uses for ranking. It is the source of truth.
  • Lab data (Lighthouse, WebPageTest) runs a single simulated load in a controlled environment. It is reproducible and excellent for debugging — it tells you why something is slow — but it is one synthetic run, not a representative population.

The practical workflow: use lab tools to diagnose and iterate quickly, then confirm improvements in field data over the following weeks. A common trap is celebrating a perfect Lighthouse score while field INP stays poor, because Lighthouse’s interactivity estimate doesn’t capture the messy reality of real users clicking real things.

LCP: Largest Contentful Paint

What it measures

LCP marks the moment the largest content element in the viewport finishes rendering — usually the hero image, a large heading, or a prominent block of text. It answers the user’s gut question: “has the main thing I came for appeared yet?” A good LCP is 2.5 seconds or less.

Why LCP is usually an image problem

In the overwhelming majority of cases, the LCP element is an image, and the image is slow for one of a few reasons: it’s too large in bytes, served in an outdated format, not prioritized in the loading sequence, or accidentally deferred. Fix the image and you usually fix LCP.

How to fix LCP

Compress and right-size the hero image. A 4000px-wide photo displayed at 800px is wasting ~75% of its bytes. Resize the image to roughly its display size (times device pixel ratio for retina) and compress it. A 60–80% file-size reduction on the LCP image directly cuts load time. Use an Image Compressor and Image Resizer to do both, and serve the right size per device with srcset.

Serve modern formats. WebP is ~25–35% smaller than JPEG at equal quality; AVIF is smaller still. Converting the hero to WebP or AVIF is one of the highest-leverage LCP improvements available.

Preload the LCP image. Tell the browser to fetch the hero early instead of discovering it late in HTML parsing:

<link rel="preload" as="image" href="/hero.avif" fetchpriority="high">

Never lazy-load the above-the-fold hero. loading="lazy" is great for below-the-fold images but catastrophic for the LCP element — it tells the browser to delay the very thing LCP is timing. Lazy-load everything except what’s visible on load.

Address render-blocking resources. Large blocking CSS and synchronous JavaScript in the <head> delay the first paint. Inline critical CSS, defer non-critical scripts, and use font-display: swap so a web font doesn’t hold back text rendering.

Optimize SVGs and inline icons. If your LCP is a vector logo or illustration, run it through an SVG Optimizer to strip metadata and shrink the payload.

INP: Interaction to Next Paint

What it measures — and why it replaced FID

INP is the metric most teams misunderstand because it’s new and stricter. Where the old FID only measured the delay before the first interaction was processed — a narrow, often flattering number — INP measures the full latency of interactions across the entire page lifetime, from the moment a user clicks, taps, or types to the moment the screen visually updates in response. It reports (roughly) the worst interaction latency a user experienced.

This is a much harder, much fairer test. A page could ace FID (the first click was fast) yet feel sluggish every time afterward; INP catches that. A good INP is 200 milliseconds or less.

Why INP is a main-thread problem

INP is fundamentally about the main thread — the single thread where JavaScript runs and the browser paints. When the main thread is busy executing a long task, it cannot respond to the user’s click or paint the next frame. Every interaction that lands during a long task is stuck waiting. INP is therefore, almost always, a JavaScript-execution problem.

How to fix INP

Break up long tasks. Any script that runs for more than ~50ms blocks responsiveness. Split heavy work into smaller chunks and yield back to the browser between them (with setTimeout, requestIdleCallback, or the newer scheduler.yield()), so the browser can process a pending click in the gap. The goal: no single task monopolizes the main thread.

Defer non-critical JavaScript. Third-party scripts — analytics, chat widgets, ad tags, A/B testing — are frequent INP killers because they execute on the main thread at inconvenient times. Load them with async/defer, delay them until after interaction, or move what you can off the main thread into a Web Worker.

Keep event handlers lean. A click handler that synchronously does expensive work (a big DOM update, a heavy computation, a layout-thrashing read/write loop) delays the next paint. Do the minimum needed to acknowledge the interaction immediately (update the button state), then schedule the heavy work afterward.

Avoid layout thrashing. Reading a layout property (like offsetHeight) right after writing one forces a synchronous reflow. In a loop, this is devastating. Batch reads, then writes.

Reduce DOM size. A large DOM makes every style recalculation and layout more expensive, inflating interaction latency. Virtualize long lists so only visible rows exist in the DOM.

The mental model: INP is the price of a busy main thread. Every millisecond you spend not blocking it is a millisecond closer to passing.

CLS: Cumulative Layout Shift

What it measures

CLS quantifies how much the page jumps around unexpectedly while it loads. You’ve felt it: you go to tap a button, an image loads above it, the layout shifts, and you tap an ad instead. CLS sums these unexpected shifts into a score; a good CLS is 0.1 or less. Crucially, only unexpected shifts count — a shift you caused by clicking (an accordion opening) is expected and excluded.

Why CLS is a reserved-space problem

Layout shift happens when content arrives without space reserved for it, so everything below reflows. The classic culprits are images and embeds with no dimensions, web fonts that swap and resize text, and content injected above existing content.

How to fix CLS

Always reserve space for images and video. This is the single biggest CLS fix. Set the intrinsic width and height attributes on every <img> and <video> — modern browsers read them as an aspect ratio and reserve the correct space before the file loads, so nothing jumps:

<img src="/photo.avif" width="1600" height="900" alt="...">

For elements with no intrinsic ratio (background-image divs, iframes, embeds), use the CSS aspect-ratio property to reserve the box. An Aspect Ratio Calculator helps you derive the correct ratio. This one practice eliminates the majority of real-world CLS.

Never inject content above existing content. A cookie banner, a notification bar, or a late-loading ad that pushes the page down is a guaranteed layout shift. Reserve its space ahead of time, or overlay it instead of inserting it into the flow.

Tame web fonts. A font swap that changes text metrics shifts everything around it. Use font-display: swap with a well-matched fallback (via size-adjust and the f-mods descriptors) so the swap doesn’t reflow, and preload critical fonts.

Avoid animating layout properties. Animating width, height, top, or margin causes reflow and can register as shift. Animate transform and opacity instead — they’re composited and don’t move surrounding content.

A practical optimization workflow

Optimizing Core Web Vitals is iterative. A reliable loop:

  1. Get field data. Start from your Chrome User Experience Report data (or RUM). It tells you which of the three vitals is actually failing for real users — don’t guess.
  2. Diagnose in the lab. Use Lighthouse and the Performance panel to find the cause of the failing metric: which element is the LCP, which interaction has the worst INP, which element shifts.
  3. Fix the biggest lever first. Usually that’s the hero image (LCP), a heavy third-party script (INP), or unsized media (CLS).
  4. Verify in lab, then confirm in field. Lab confirms the fix works; field data over the following weeks confirms it moved the 75th percentile.
  5. Repeat. Vitals drift as you ship features. Treat them as an ongoing budget, not a one-time project.

Common mistakes that keep teams stuck

  • Optimizing for Lighthouse, not users. A 100 Lighthouse score with poor field INP means real users are suffering while a synthetic test passes. Field data is the truth.
  • Ignoring the 75th percentile. Averages hide your slow users. The 75th percentile is where you live or die.
  • Lazy-loading the hero image. The most common LCP self-own. Lazy-load below the fold only.
  • Treating INP like FID. Fast first-click is not enough; every interaction must stay responsive. Profile the slow ones.
  • Forgetting image dimensions. Unsized images are the number-one cause of CLS, and the fix is trivial.
  • Blaming the framework. Most CWV failures are content and main-thread issues, not the framework. Profile before you re-architect.

Beyond the big three: supporting metrics

The three Core Web Vitals are the headline metrics, but a few supporting measurements help you diagnose them and round out the performance picture. They aren’t ranking factors themselves, but they’re causally upstream of the ones that are.

TTFB (Time to First Byte) measures how long the server takes to send the first byte of the response after the browser requests it. It’s the foundation everything else builds on: if TTFB is slow, LCP can’t be fast, because the browser is still waiting for HTML before it can even discover the hero image. High TTFB points at server-side problems — slow database queries, unoptimized backend code, no caching, or a distant origin server. Fixes include caching responses, using a CDN to serve from locations near users, and optimizing backend work. A good TTFB is generally under ~800ms, and well-optimized sites achieve far less.

FCP (First Contentful Paint) marks when the first content — any text or image — appears, as opposed to LCP’s largest content. FCP tells you when the page stops being blank. A slow FCP usually indicates render-blocking resources (large synchronous CSS or JavaScript in the <head>) delaying the first paint. Improving FCP — by inlining critical CSS, deferring non-critical scripts, and reducing TTFB — typically improves LCP too, since they share many causes.

Total Blocking Time (TBT) is a lab metric that approximates what INP measures in the field. It sums the time the main thread was blocked by long tasks during load. Because INP can only be measured with real users (it needs real interactions), TBT is your lab proxy for responsiveness: drive it down in Lighthouse and your field INP usually follows. If TBT is high, you have long main-thread tasks — the exact thing that wrecks INP — and the same fixes (breaking up tasks, deferring scripts) apply.

The relationships form a chain: TTFB → FCP → LCP for loading, and TBT (lab) ↔ INP (field) for responsiveness. When a Core Web Vital is failing, these supporting metrics tell you where in the chain the problem lives, turning “LCP is slow” into the actionable “TTFB is the bottleneck” or “a render-blocking script is delaying first paint.”

Performance budgets: keeping vitals from regressing

Passing Core Web Vitals once is easy; staying passed as your team ships features for months is hard. Every new third-party script, every unoptimized image a content editor uploads, every added dependency nudges the metrics in the wrong direction, and without a guardrail you discover the regression only when rankings or conversions drop.

The guardrail is a performance budget: explicit limits on the things that drive the vitals — total JavaScript size, image weight per page, number of third-party requests, or the metrics themselves. You enforce it in continuous integration, so a pull request that pushes the bundle over budget or regresses the Lighthouse score fails the build before it ships, the same way a failing test would. This shifts performance from a periodic cleanup project to a continuous constraint the whole team works within.

The practical setup: measure the current values, set budgets slightly tighter than today’s numbers (so you can’t get worse), and wire a tool like Lighthouse CI into your pipeline to check every change. Pair it with ongoing real-user monitoring so you catch field regressions the lab can’t see. Treating Core Web Vitals as a budget rather than a one-time audit is the difference between a site that passes this quarter and a site that stays fast for years.

Why Core Web Vitals are worth the effort

Beyond the SEO signal — and Core Web Vitals are a page-experience ranking factor, most decisive as a tiebreaker between comparable pages — performance is a conversion and revenue lever. Faster loads, snappier interactions, and stable layouts measurably reduce bounce and increase engagement and conversion. Numerous case studies tie improvements in these exact metrics to double-digit gains in conversion and session depth. You are not optimizing a number for Google; you are removing friction for the human on a mid-range phone trying to use your site.

The metrics also map cleanly to real user pain: LCP is “I’m staring at a blank page,” INP is “I tapped and nothing happened,” CLS is “the page jumped and I clicked the wrong thing.” Fixing them fixes the experience, and the ranking benefit follows.

Conclusion

Core Web Vitals reduce web performance to three honest questions: did the main content load fast (LCP ≤ 2.5s), did the page respond quickly to every interaction (INP ≤ 200ms), and did the layout stay stable (CLS ≤ 0.1)? The 2024 shift from FID to INP raised the responsiveness bar and caught many teams optimizing for the wrong thing. The fixes, though, are well-understood: compress, size, and preload the hero image for LCP; break up long main-thread tasks and defer third-party scripts for INP; and reserve space for every image and embed for CLS. Start by pulling your field data to see which vital is failing, fix the single biggest lever, and confirm the improvement in real-user data. Done consistently, this playbook turns Core Web Vitals from a recurring audit failure into a durable competitive advantage — for both your rankings and your users.

Necmeddin Cunedioglu
Necmeddin Cunedioglu Author
12 min read
-- views

Software developer and the creator of UseToolSuite. I write about the tools and techniques I use daily as a developer — practical guides based on real experience, not theory.