Core Web Vitals
LCP, INP, and CLS — what field data measures, good thresholds, and fixes that actually move the needle (per web.dev guidance).
- performance
- web-vitals
- lcp
- inp
- cls
Core Web Vitals are Google’s field-oriented UX metrics. Lab tools (Lighthouse) help you debug. Production RUM / CrUX is what tells you if real users are fine.
Measure the 75th percentile, mobile and desktop separately. One fast laptop on Wi‑Fi is not a product.
The three (today)
| Metric | Question it answers | “Good” |
|---|---|---|
| LCP | How fast does the main content show up? | ≤ 2.5s |
| INP | How responsive is the page to clicks/taps/keys over the whole visit? | ≤ 200ms |
| CLS | How much does the layout jump around unexpectedly? | ≤ 0.1 |
FID is retired. INP replaced it as the interactivity Core Web Vital.
LCP — largest contentful paint
Usually a hero image, big text block, or video poster. Users decide “is this useful?” around here.
Fixes that web.dev keeps repeating for a reason:
- Make the LCP resource discoverable in the initial HTML (not injected late by JS).
- Prioritize it —
fetchpriority="high", preload when needed, don’tloading="lazy"the LCP image. - Shrink bytes: modern formats, right dimensions, CDN, good compression.
- Cut render-blocking work on the critical path.
- Server-render meaningful text when you can — text LCP often beats a late image.
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high" />
<img
src="/hero.avif"
width="1200"
height="630"
alt=""
fetchpriority="high"
/>
TTFB still matters: a slow document delays everything downstream. CDN and caching are LCP tools too.
INP — interaction to next paint
Most of a session happens after load. INP watches click / tap / key interactions across the life of the page and reports a high-percentile latency (not “first click only” like FID).
An interaction’s latency is roughly:
input delay → handler work → time until the next paint
Good responsiveness is not “all network finished.” It’s “the user saw a reaction soon” — accordion opens, button depresses, spinner appears.
Thresholds (75th percentile):
- ≤ 200ms → good
- ≤ 500ms → needs improvement
- > 500ms → poor
What actually helps:
- Break up long tasks so the main thread can paint and take input (yield with macrotasks /
scheduler.yield). - Keep event handlers thin — defer non-critical work.
- Avoid forced layout thrash in handlers.
- Virtualize huge lists; don’t re-render the world on every keystroke.
- Audit third-party scripts that monopolize the main thread.
// Sketch: yield between chunks (prefer platform APIs when available)
async function processAll(items) {
for (let i = 0; i < items.length; i++) {
doWork(items[i]);
if (i % 50 === 0) {
await new Promise((r) => setTimeout(r, 0));
}
}
}
Lab note: INP depends on which interactions you perform. Field data + reproducing the slow interaction beats staring at a load-only Lighthouse run. TBT can be a rough proxy in the lab; it is not INP.
CLS — cumulative layout shift
Unexpected movement of visible content. Classic causes: images without dimensions, late ads/fonts/banners shoved above existing content, dynamic injection.
Fixes:
- Always reserve space (
width/heightoraspect-ratio). - Don’t insert banners above content without a reserved slot.
- Font strategy that limits layout swap pain (
size-adjust, matched fallbacks, carefulfont-display). - Prefer
transformanimations over top/left that reflow.
.card-media {
aspect-ratio: 16 / 9;
background: var(--color-bg-muted);
}
Measure like an adult
Field: CrUX (via PageSpeed Insights), your own RUM with the web-vitals library.
import { onLCP, onINP, onCLS } from 'web-vitals';
onLCP(console.log);
onINP(console.log);
onCLS(console.log);
Lab: Lighthouse, WebPageTest, Performance panel — great for why, incomplete for is production good.
Interview framing
Define each metric in one sentence, name the good threshold, give one root cause + one fix, and mention field vs lab. That package beats reciting three numbers alone.
Further reading (web.dev / Chrome)
Related
Related guides
- Measuring Performance MindsetMeasuring Performance Mindset explained for frontend engineers — mental model, examples, common mistakes, and interview tips.
- Lab vs Field DataLab vs Field Data explained for frontend engineers — mental model, examples, common mistakes, and interview tips.
- LCP Optimization TacticsLCP Optimization Tactics explained for frontend engineers — mental model, examples, common mistakes, and interview tips.
- INP Optimization TacticsINP Optimization Tactics explained for frontend engineers — mental model, examples, common mistakes, and interview tips.
- CLS Optimization TacticsCLS Optimization Tactics explained for frontend engineers — mental model, examples, common mistakes, and interview tips.