Blog

Core Web Vitals from real users: LCP, INP and CLS explained, and how to track them

Core Web Vitals are Google's three metrics for how a page feels to a real visitor: how fast the main content shows up, how quickly the page responds, and whether things jump around while it loads. They're part of Google's page experience signals, but the bigger reason to care is simpler: slow, jumpy pages lose visitors and sales.

The three metrics

MetricWhat it measuresGoodPoor
LCP, Largest Contentful PaintTime until the largest image or text block in the viewport is rendered≤ 2.5 s> 4 s
INP, Interaction to Next PaintDelay between a click, tap or key press and the next visual update, for (nearly) the slowest interaction on the page≤ 200 ms> 500 ms
CLS, Cumulative Layout ShiftHow much visible content moves unexpectedly (largest burst of shifts)≤ 0.1> 0.25

Google assesses each metric at the 75th percentile of page loads: a page passes when at least 75% of visits are in the "good" range. INP replaced First Input Delay (FID) as a Core Web Vital in March 2024.

Lab data vs field data

Lighthouse and PageSpeed Insights' lab section load your page once, on a simulated device and network. That's great for debugging, but it isn't what your visitors experience:

Field data (real user monitoring, RUM) comes from the browsers of actual visitors. Google's own field data is the Chrome UX Report (CrUX), which you see in Search Console and PageSpeed Insights, but it only covers Chrome users who opted in, is aggregated over 28 days, and is missing entirely for pages with little traffic.

Collecting Web Vitals yourself

Browsers expose the raw data through the PerformanceObserver API (largest-contentful-paint, layout-shift and event entries). Google's open-source web-vitals library wraps the edge cases, such as background tabs and back/forward cache restores:

import { onLCP, onINP, onCLS } from 'web-vitals';

function send(metric) {
  navigator.sendBeacon('/vitals', JSON.stringify({
    name: metric.name, value: metric.value, page: location.pathname,
  }));
}
onLCP(send); onINP(send); onCLS(send);

Then store the values per page and report the 75th percentile. Browser support differs: Chromium browsers have had all three APIs for years, while Safari and Firefox added them later and only in recent versions, so check which browsers your field numbers actually come from.

Fixing the usual suspects

Web Vitals next to your traffic

A per-page score is most useful next to how much traffic and money that page brings: a slow page with five visits a month can wait; a slow pricing page can't. PageLens collects LCP, INP and CLS from real visitors with the same lightweight script that counts traffic, and shows the 75th percentile per page on the Performance page, with no extra setup.

Try PageLens on your site

Create a free PageLens account: 7-day trial, no card, no cookie banner needed.

Start free trial

Keep reading