Core Web Vitals in plain English
LCP, INP and CLS explained without jargon: what each one measures, what usually breaks it, and the change that most often moves it.
Core Web Vitals are three measurements meant to stand in for three ordinary human complaints: it took too long to show up, it did not react when I tapped, and it moved while I was reading. Stripped of the acronyms they are straightforward, and each one has a short list of usual causes. This guide explains what each measures, what typically breaks it, and the change that most often fixes it.
Largest Contentful Paint: "it took too long to show up"
LCP measures how long until the biggest thing on the first screen is visible — normally a hero image, a banner or a block of headline text. It is the closest single number to the moment a visitor feels the page has arrived.
What usually breaks it
- A slow server response, which delays everything downstream. If the first byte takes a second, LCP cannot be good.
- The hero image being lazy-loaded, discovered late, or served far larger than the space it occupies.
- Render-blocking CSS or synchronous scripts in the head.
- The main content being rendered by client-side JavaScript, so the browser must download and run a bundle before it can paint anything meaningful.
- A web font that hides text until it loads, when the largest element is text.
What usually fixes it
- Preload the hero image and never lazy-load it; serve it sized for the viewport in a modern format.
- Render the first screen's content on the server or statically.
- Move non-critical scripts out of the critical path and inline only the CSS the first screen needs.
- Use font-display: swap so text paints immediately.
Target
Interaction to Next Paint: "it did not react when I tapped"
INP measures the delay between a user interaction and the browser actually showing a visual response, across the whole visit. It captures the frustration of a button that looks pressed but does nothing for half a second.
This metric is overwhelmingly about main-thread availability. When a long task is running, the browser cannot handle the tap, run your handler or paint the result — it simply waits. On a mid-range phone, tasks that are imperceptible on a laptop become clearly visible stalls.
What usually breaks it
- Long JavaScript tasks: hydration, large list rendering, client-side sorting or filtering, heavy work inside event handlers.
- Expensive work on every keystroke or scroll event without debouncing.
- Third-party scripts running their own long tasks at unpredictable times.
- Handlers that force layout by reading geometry and then writing styles repeatedly.
- Rendering an entire list when a single row changed.
What usually fixes it
- Break long work into chunks that yield to the browser between them, so input is handled promptly.
- Give immediate visual feedback first — a pressed state, a spinner — and do the expensive work after the paint.
- Virtualise long lists so only visible rows render.
- Move genuinely heavy computation off the main thread.
- Debounce input-driven work and cache derived results instead of recomputing them.
Target
Cumulative Layout Shift: "it moved while I was reading"
CLS measures how much visible content jumps around during loading. It is the metric behind tapping a link and hitting an advert instead because a banner appeared above it.
What usually breaks it
- Images and videos without dimensions or an aspect ratio, so the browser cannot reserve space.
- Advert and embed slots that collapse to zero height until content arrives.
- Banners, cookie notices and promotional bars injected at the top of the document after render.
- Fonts that swap to a metrically different family, reflowing paragraphs.
- Content inserted above existing content — the single worst offender, because it moves everything the user is already looking at.
What usually fixes it
- Set width and height, or aspect-ratio, on every image, video and embed.
- Reserve fixed space for advert slots and dynamic modules, including when they are empty.
- Overlay notices rather than pushing the document down.
- Match fallback font metrics to the web font so the swap does not reflow text.
- Animate with transform rather than properties that change layout.
Target
Lab numbers versus field numbers
A lab tool runs one page once in a controlled environment. Field data comes from real visits on real devices and networks. They disagree regularly, and when they do, the field is right — it includes the phones, connections and conditions your lab never simulated.
Use lab measurement to iterate quickly while making a change, and field measurement to decide whether the change mattered. If you have no field data, the next best thing is measuring on the slowest device you support, in conditions resembling your users' rather than your office's.
Where device capability fits in
Vitals describe outcomes; device capability explains them. A page with an identical payload can post a good INP on a laptop and a poor one on a three-year-old phone, purely because the hardware processes the same JavaScript several times more slowly. Knowing the processor, memory, layout and compositing headroom of your floor device tells you how much work you can afford before the vitals move.
That is the practical link between these metrics and hardware measurement: read your device score to learn the budget, then work through the page-load checklist to spend it well.
Keep reading
Reading a device performance score
What the CPU, memory, layout, GPU and network numbers in a device benchmark actually mean, and how to tell a real problem from normal variance.
DiagnosisFast on your laptop, slow on a phone
The hardware gap, thermal throttling, network variance and cache warmth that make developer machines a misleading place to judge performance.
OptimisationFixing slow page loads
An ordered checklist for making a page load faster, with the realistic gain and the cost of each step so you can stop at the right point.
MethodLoad testing vs real-device testing
What server-side load tools like k6 and JMeter measure, what they structurally cannot see, and when you need device-side measurement instead.