DEV Community

Cover image for LCP, INP, CLS: What Each Core Web Vital Means and How to Fix It
Apogee Watcher
Apogee Watcher

Posted on • Originally published at apogeewatcher.com

LCP, INP, CLS: What Each Core Web Vital Means and How to Fix It

The Three Numbers That Control Your Search Rankings

Google's Core Web Vitals boil down to three metrics: LCP, INP, and CLS. Each measures a different dimension of user experience, and each has specific thresholds that determine whether your page passes or fails.

This guide goes deeper than the overview. For each metric, we cover what it measures, why it matters, how to diagnose problems, and the exact steps to fix them. If you need the basics first, start with What Are Core Web Vitals?. For setting thresholds and budgets, see our performance budget resources.


LCP — Largest Contentful Paint

What It Actually Measures

LCP measures the render time of the largest content element visible in the viewport. "Largest" means the element with the biggest visual footprint, which is usually one of:

  • A <img> element (hero image, banner)
  • A <video> element's poster frame
  • A block-level element containing text (headline, paragraph)
  • A background image loaded via url() in CSS

The browser identifies the LCP element dynamically. As the page loads, the "largest" element can change — an initial text block might be the largest until a hero image finishes rendering and takes over.

Thresholds

Rating Time
Good ≤ 2.5 seconds
Needs Improvement 2.5 – 4.0 seconds
Poor > 4.0 seconds

The Four Sub-Parts of LCP

LCP isn't one bottleneck — it's four sequential steps. Fixing LCP means identifying which sub-part is slow:

1. Time to First Byte (TTFB)
The time from the request to the first byte of the HTML response. If your server is slow, everything downstream is delayed.

Fix: Optimize server-side rendering, use a CDN, implement caching, upgrade hosting.

2. Resource Load Delay
The time from TTFB to when the browser starts loading the LCP resource (image, font, etc.).

Fix: Preload the LCP resource (<link rel="preload">), inline critical CSS, remove render-blocking scripts.

3. Resource Load Duration
The time to download the LCP resource itself.

Fix: Compress images (WebP/AVIF), resize to actual display dimensions, use responsive images with srcset, serve from CDN.

4. Element Render Delay
The time from when the resource is loaded to when it's actually painted on screen.

Fix: Remove render-blocking JavaScript, reduce CSS complexity, avoid display:none toggling on LCP elements.

LCP Debugging Workflow

1. Run PageSpeed Insights on the page
2. Identify the LCP element (shown in the diagnostics)
3. Check TTFB — is the server slow?
4. Check if the LCP resource is preloaded
5. Check the file size of the LCP resource
6. Check for render-blocking resources
7. Fix the biggest bottleneck first
8. Re-test to verify improvement
Enter fullscreen mode Exit fullscreen mode

Common LCP Fixes (Ranked by Impact)

  1. Preload the LCP image — Add <link rel="preload" as="image" href="hero.webp"> to <head>
  2. Compress and resize images — Convert to WebP, size to actual display dimensions
  3. Use a CDN — Reduce download time for all resources
  4. Remove render-blocking JS — Defer or async non-critical scripts
  5. Set up server-side caching — Redis, Varnish, or CDN-level caching for HTML

INP — Interaction to Next Paint

What It Actually Measures

INP measures the delay between a user interaction (click, tap, or keypress) and the next visual update the browser paints. Unlike FID (which only measured the first interaction), INP considers every interaction during the entire page lifecycle and reports a value near the worst case (technically, the 98th percentile).

This means INP catches problems that only appear after the page has loaded — like a sluggish dropdown menu, a slow form submission, or a laggy accordion toggle.

Thresholds

Rating Time
Good ≤ 200 milliseconds
Needs Improvement 200 – 500 milliseconds
Poor > 500 milliseconds

The Three Phases of an Interaction

Every interaction has three phases:

1. Input Delay
Time from the user's action to when the event handler starts running. If the main thread is busy with other work (parsing JS, running another task), the input delay grows.

Fix: Break up long tasks, yield to the main thread, reduce third-party script load.

2. Processing Time
Time spent running the event handler code itself.

Fix: Optimize event handler logic, avoid synchronous DOM reads/writes in loops, debounce expensive operations.

3. Presentation Delay
Time from when the event handler finishes to when the browser paints the visual update.

Fix: Minimize DOM mutations, avoid forced reflows, reduce paint complexity.

INP Debugging Workflow

1. Open Chrome DevTools → Performance panel
2. Record a session while interacting with the page
3. Look for long tasks (> 50ms) near interaction events
4. Identify what code is running during the delay
5. Check if third-party scripts are blocking
6. Optimize the slowest interaction first
7. Re-test with real user monitoring
Enter fullscreen mode Exit fullscreen mode

Common INP Fixes (Ranked by Impact)

  1. Break up long tasks — Use scheduler.yield() (Chrome 108+) or setTimeout(0) to split work
  2. Defer third-party scripts — Load analytics, chat widgets, and ads after the page is interactive
  3. Reduce DOM size — Fewer nodes = faster layout calculations = faster paint
  4. Use CSS content-visibility: auto — Skip rendering of off-screen elements
  5. Debounce event handlers — Prevent rapid-fire processing on scroll, resize, input events
  6. Move heavy work to Web Workers — Keep computation off the main thread

CLS — Cumulative Layout Shift

What It Actually Measures

CLS quantifies how much visible content shifts unexpectedly during the page's lifecycle. Each time an element changes position without user action, the browser calculates a "layout shift score" based on the size of the element and the distance it moved. CLS is the sum of the largest burst of shift scores (using a "session window" approach).

A CLS of 0 means nothing shifted. A CLS of 0.1 means a noticeable but acceptable amount of movement. Anything above 0.25 is a poor experience.

Thresholds

Rating Score
Good ≤ 0.1
Needs Improvement 0.1 – 0.25
Poor > 0.25

What Counts as a Layout Shift

Not all movement counts. CLS only tracks unexpected shifts — shifts that happen without user interaction. These count:

  • An image loads and pushes content down
  • A web font renders and changes text dimensions
  • An ad slot expands and moves the content below it
  • Dynamically injected banners or notifications push content

These do NOT count:

  • Content moves because the user scrolled
  • Content shifts after a click or tap
  • Smooth CSS animations/transitions

CLS Debugging Workflow

1. Run PageSpeed Insights — check CLS score and flagged elements
2. Open Chrome DevTools → Performance panel → check "Layout Shifts"
3. Enable the "Layout Shift Regions" overlay in DevTools
4. Identify which elements are shifting and why
5. Check for images/videos without dimensions
6. Check for dynamically injected content
7. Check for font-related shifts (FOUT/FOIT)
8. Fix and re-test
Enter fullscreen mode Exit fullscreen mode

Common CLS Fixes (Ranked by Impact)

  1. Set explicit dimensions on images and videos — Always use width and height attributes or CSS aspect-ratio
  2. Reserve space for ad slots — Use min-height or aspect-ratio on ad containers
  3. Preload fonts and use font-display: optional — Prevents FOUT/FOIT-related shifts
  4. Avoid inserting content above the fold after load — If you must, use CSS transforms instead of layout-changing properties
  5. Use contain: layout on components — Prevents shifts from propagating to parent containers
  6. Pin dynamic banners to fixed positions — Sticky banners at top or bottom don't cause layout shifts

Putting It All Together

Priority Order for Fixing

If all three metrics are poor, fix them in this order:

  1. LCP first — It has the biggest impact on perceived speed and is usually the easiest to improve
  2. CLS second — Often requires simple HTML/CSS changes (adding dimensions, reserving space)
  3. INP last — Usually requires JavaScript refactoring, which takes more time

Monitoring All Three

Fixing CWV once isn't enough. New deployments, content changes, third-party script updates, and CMS modifications can regress any metric at any time. You need ongoing monitoring that:

  • Tests pages on a schedule
  • Tracks all three metrics over time
  • Alerts you when any metric crosses a threshold
  • Reports trends to stakeholders

This is where automated monitoring platforms make the difference. Instead of manually running PageSpeed Insights on every page after every deploy, a tool like Apogee Watcher runs tests automatically and notifies you the moment something degrades.

When to Get Help

Some fixes require deep expertise. Consider bringing in a specialist or agency when:

  • INP issues persist after deferring scripts and breaking up tasks (may need framework-level changes)
  • LCP is dominated by third-party content you don't control (ads, embeds)
  • You've applied the quick wins and scores haven't improved
  • You're on a tight deadline and need results fast

Quick Reference Card

Metric Measures Good Needs Improvement Poor
LCP Loading speed ≤ 2.5s 2.5s – 4.0s > 4.0s
INP Interactivity ≤ 200ms 200ms – 500ms > 500ms
CLS Visual stability ≤ 0.1 0.1 – 0.25 > 0.25

Monitoring LCP, INP, and CLS across all your sites shouldn't be manual work. Join the Apogee Watcher waitlist for automated Core Web Vitals monitoring with alerts and reporting.

Top comments (0)