Core Web Vitals — Cheat Sheet

FE Lead prep · ref 03

The three (thresholds @ p75, field data)

MetricMeasuresFeelingGoodPoor
LCP Largest Contentful Paintloadingdid it load?≤ 2.5s> 4s
INP Interaction to Next Paintresponsivenessdoes it react?≤ 200ms> 500ms
CLS Cumulative Layout Shiftvisual stabilitydoes it hold still?≤ 0.1> 0.25
Pass = ≥ 75% of real visits hit “good”. Between good & poor = “needs improvement”. INP replaced FID, Mar 2024.

Lab vs Field

Lab (Lighthouse/DevTools)Field (CrUX / RUM)
whatone synthetic runreal users, p75
usedebug — tells you whygraded — tells you whether
INP?can't (no real interaction; shows TBT proxy)yes

Supporting metrics (the timeline)

TTFB → FCP → LCP → TBT/TTI → INP  (bold = the vital)
MetricIsGoodRole
TTFBreq → first byte (server+net)≤ 0.8scaps LCP — precursor to all
FCPfirst any content painted≤ 1.8sfirst sign of life → LCP
TBTΣ long-task blocking after FCP< 200ms (lab)lab proxy for INP
TTImain thread quiet ~5s post-FCPdeprecated (Lighthouse 10) → use TBT

INP = 3 phases

PhaseIsFix
Input delaymain thread busybreak long tasks, yield, less JS
Processinghandler JS runsminimal sync work, debounce
Presentationpaint next framevirtualize, content-visibility

Cause → fix (quick)

CLS formula

score = impact × distance

INP in React

Lead one-liners (memorize)

The three  “LCP = did it load, INP = does it react, CLS = does it hold still. Good = 2.5s / 200ms / 0.1, at p75 of real users.”
Lab vs field  “Lab tells you why; field tells you whether. I debug in Lighthouse but I'm graded on p75 field data.”
Timeline  “TTFB → FCP → LCP is the loading timeline; TBT is the lab proxy for INP. TTI is legacy — I quote TBT now.”

Platform mapping

Sources: web.dev — INP · Google — Core Web Vitals · web.dev — thresholds

Don't fail the interview

1. It's field data at p75, not your laptop. Debug in lab, graded in field.
2. Lighthouse can't measure INP (no real interactions) — green lab ≠ good INP.
3. INP ≠ FID. FID = first interaction's input delay only; INP = full latency, all interactions.
4. Never lazy-load the LCP element (hero). Lazy-load below the fold only.
5. Lead answer = RUM p75 + perf budget in CI, not “I ran Lighthouse.”
6. TTI is deprecated (Lighthouse 10, too variable). Lab responsiveness = TBT; field = INP. Citing TTI dates you.
7. TTFB caps LCP — a slow first byte means no preload will save you. Fix the server/CDN first.
8. CLS = impact × distance (multiply, never add), worst 5s session window; sub-500ms-post-input shifts are free.
9. Bundle budget ≠ Lighthouse budget. Bundle gates the artifact (JS/CSS bytes); Lighthouse gates the rendered page (real LCP/CLS + images + 3rd-party). Run both in CI (@lhci/cli); fails the build. budget.json OR assertions, not both.