Frontend engineer path · The network and the user · Topic 14 of 17

Core Web Vitals: LCP, INP and CLS

Not started

Core Web Vitals are three measurements of what a real visitor experiences: how soon the main content appears (Largest Contentful Paint), how quickly the page reacts when they interact (Interaction to Next Paint), and how much the layout jumps around (Cumulative Layout Shift). They are measured on real visits and judged at the 75th percentile, so a fast laptop on office Wi-Fi tells you little about them.

Why it matters: These three numbers are how Google, and most teams, judge whether a page feels fast. Each one has a short list of causes you can actually fix.

  1. 1LCP, loading

    When the largest image or text block in the viewport has rendered. Good is 2.5 seconds or less; poor is over 4.

  2. 2INP, responding

    The slowest typical delay from a click, tap or key press to the next frame, over the whole visit. Good is 200 ms or less; poor is over 500.

  3. 3CLS, staying still

    The worst burst of unexpected layout shifts. Good is 0.1 or less; poor is over 0.25.

  4. 4Judged at the 75th percentile

    A page passes when at least 75% of real visits, on mobile and on desktop separately, are good on all three.

1

How it works

The explanation, with examples you can run.

LCP: get the main thing on screen

LCP is the render time of the largest image, video poster or text block visible in the viewport. It splits into four parts, and each has its own fixes:

  • Time to first byte: a slow server or a long redirect chain. Cache HTML at a CDN where possible, and avoid redirects.
  • Resource load delay: the time before the browser even requests the LCP image. Put it in the HTML as an <img> rather than a CSS background or a script, add fetchpriority="high", and never loading="lazy" on it.
  • Resource load duration: the download. Serve a compressed, correctly sized image (srcset, AVIF or WebP) from a nearby cache.
  • Element render delay: the file has arrived, but render-blocking CSS, a script or a client-side render is holding up the paint.

INP: answer the user quickly

INP looks at the interactions of the whole visit (clicks, taps, key presses; not scrolling or hovering) and reports roughly the worst one. Each interaction is input delay (the main thread was busy), processing time (your handlers) and presentation delay (style, layout and paint of the next frame). INP replaced First Input Delay, which only measured the first interaction's input delay. To keep it low: break long tasks into smaller ones, show visual feedback before doing the heavy work, keep the DOM small so each update renders quickly, and watch third-party scripts, which share your main thread.

CLS: don't move things under the user

Each unexpected shift scores the share of the viewport affected times the distance moved. Shifts are grouped into session windows (gaps under 1 second, at most 5 seconds long), and CLS is the worst window. Shifts within 500 ms of a tap, click or key press are excluded, because the user expected something to change.

⌘/Ctrl + Enter
OutputNot run yet

Press Run to see what your code prints, in order.

Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.

The usual causes are images and embeds without dimensions, content injected above what is already shown, and web fonts that swap in with different metrics. Give media width and height (or aspect-ratio), reserve space for late content, and animate with transform rather than properties that move other boxes.

Measure in the field (the Chrome UX Report, or the web-vitals library sending data to your analytics) and debug in the lab (Lighthouse, the DevTools Performance panel). INP is the hardest to reproduce in the lab: a page-load test only measures it if you script the interactions yourself, so start from field data to learn which interactions are slow.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.The LCP element is a hero image set as a CSS background, and LCP is 4.5 s. What is the most direct fix?
  2. 2.Clicking 'Add to cart' runs a 400 ms handler before the button shows any change. Which metric suffers, and what helps?
  3. 3.Ads load into a slot with no height and push the article down. What fixes the CLS?

0 of 3 right so far. Get all three to finish this topic.