Performance Metrics, in focus.
Six numbers decide how fast a page feels — not how fast it technically loads. This is what each one measures, the threshold that counts as "good", and the specific lever that moves it.
Six numbers that define how fast it feels
Each metric fires at a different point in the page lifecycle — from the server's first byte to the user's first tap. Read them left-to-right as a timeline of perceived speed.
When each metric fires
Fig. 1 — TTFB and FCP gate the start; LCP marks the main content; INP and CLS are measured across the entire page lifetime, not just load.
The thresholds, at a glance
| Metric | What it measures | Good | Needs work | Poor |
|---|---|---|---|---|
TTFBTime to First Byte |
How quickly the server starts replying | ≤ 800ms | ≤ 1.8s | > 1.8s |
FCPFirst Contentful Paint |
When the user sees anything at all | ≤ 1.8s | ≤ 3s | > 3s |
LCP CWVLargest Contentful Paint |
When the main content lands | ≤ 2.5s | ≤ 4s | > 4s |
CLS CWVCumulative Layout Shift |
How much the layout jumps while loading | ≤ 0.1 | ≤ 0.25 | > 0.25 |
INP CWVInteraction to Next Paint |
Whether every tap and click feels instant | ≤ 200ms | ≤ 500ms | > 500ms |
TBTTotal Blocking Time |
How long the main thread is hogged during load | ≤ 200ms | ≤ 600ms | > 600ms |
Fig. 2 — The three marked CWV are Google's Core Web Vitals and feed Search ranking. Thresholds are p75 field data.
What each one is really telling you
<link> / <script> in <head>, unoptimised critical CSS, and font-display: block.fetchpriority="high", or SSR hydration delays.Fix the metric, not just the score
Each metric has a small set of high-leverage fixes. Work backward from the symptom to the cause, in roughly this order of impact.
Fixing LCP — get the largest element painted in 2.5s
fetchpriority="high" to the hero <img> and loading="eager" (never lazy above the fold). For CSS background images, add a <link rel="preload"> in <head>. Impact: very high.<picture> + responsive srcset, from the nearest edge. A 2MB hero JPEG that becomes a 180KB AVIF shaves ~800ms on median mobile. Impact: high.Fixing INP — keep all three phases under 200ms
await scheduler.yield() (Chrome 115+) or setTimeout(0) breaks long handlers into chunks, letting the browser paint between tasks. Impact: very high.startTransition() so the click feedback paints first. Impact: high in React apps.postMessage. Impact: high for compute-heavy pages.offsetHeight / getBoundingClientRect right after a style write forces a sync recalc. Batch reads before writes, or schedule reads in requestAnimationFrame. Impact: medium–high.Fixing CLS — reserve the space upfront
width/height attrs (or CSS aspect-ratio) let it allocate space ahead of time. Impact: very high — the most common cause.font-display: optionalsize-adjust + ascent-override. Impact: high.min-height on their containers, or use skeletons matching final dimensions. Impact: high.Fixing TTFB — a server and network concern
Cache-Control with stale-while-revalidate to serve instantly while refreshing in the background. Impact: very high.103 Early Hints lets the server send preload hints for fonts and hero images before the 200 OK is ready, so the browser fetches during server think time — shaving 200–500ms off perceived LCP. Impact: medium–high.Fixing TBT — ship less JS, or run it later
import() means only the current page's code loads upfront. An 800KB main bundle where 200KB suffices wastes 300–600ms of parse + eval. Impact: very high.async/defer, load after interaction (facade pattern), or swap for lighter alternatives. Impact: high.browserslist target (no IE11) and check the bundle for core-js polyfilling APIs you already support. @babel/preset-env with useBuiltIns: 'usage' + corejs: 3 keeps it surgical. Impact: medium.What is AMP, and does it still matter?
AMP is an open-source HTML framework Google launched in 2015. Instead of hoping developers write fast pages, it makes it structurally impossible to write slow ones — by banning custom JS, requiring async-only scripts, pre-sizing all media, and serving pages from the Google AMP Cache built into Search.
The constraints AMP enforces
amp-* components run by the AMP runtime; custom <script> fails validation. This eliminates TBT entirely by design.layout, width, and height before rendering — structurally preventing CLS.Typical metric comparison (p75)
Regular mobile page
| LCP | 3.8s |
| CLS | 0.18 |
| TBT | 480ms |
| TTFB | 1.2s |
| FCP | 2.6s |
⚡ AMP page (from Search)
| LCP | 0.9s |
| CLS | 0.01 |
| TBT | 0ms |
| TTFB | ~0ms |
| FCP | 0.6s |
The honest verdict
Working against it
- The SEO incentive is gone. Since 2021, regular pages meeting Core Web Vitals qualify for Top Stories — AMP is no longer required.
- Pages serve from google.com. The URL is
google.com/amp/yoursite.com; users never see your domain, hurting brand trust and breaking analytics attribution. - Severe DX cost. No custom JS, no standard CSS animations, a custom component library to learn — many interactive patterns are painful or impossible.
Still in its favour
- Great for editorial / news. Purely informational articles and landing pages build in AMP with minimal sacrifice, and the gains are real.
- The ideas are now standard. No render-blocking resources, pre-sized media, inlined critical CSS — exactly what Lighthouse and CWV push you toward anyway. AMP made them mainstream.
The bottom line
"Optimise for what the user perceives: TTFB and FCP gate the start, LCP marks the main content, and INP and CLS govern how it behaves once it's there. The three Core Web Vitals — LCP, CLS, INP — are the ones Google ranks on. For a new project, hit those thresholds natively with good engineering rather than reaching for AMP; the performance delta is smaller than it used to be, and AMP only ever made sense when it was the one reliable path to the Search carousel — which it no longer is."
Five follow-ups you should be ready for
- Why did INP replace FID? FID only measured the delay before the first interaction's handler ran. INP measures full interaction latency (input delay + processing + presentation) across the whole page life, at the 98th percentile.
- Why is TBT lab-only? It needs the full set of long tasks between FCP and TTI, available in synthetic runs (Lighthouse) but not from real users — where INP is collected instead.
- What inflates CLS the most? Images and ad/embed slots without reserved space. Set dimensions or
aspect-ratioandmin-heighton containers. - Can frontend work fix TTFB? No — it's a server/network metric. Edge caching, DB tuning, and 103 Early Hints are the levers.
- Is AMP still worth adopting? Rarely for new projects. Hit Core Web Vitals natively; reserve AMP for static editorial content where the constraints don't hurt.
Before you leave — how confident are you with this?
Your honest rating shapes when you'll see this again. No grades, no shame.
Comments
Loading comments…