Core Web Vitals are the three metrics Google uses to measure real-world user experience — and unlike older performance metrics, they measure what users actually perceive, not just raw load time.
LCP — Largest Contentful Paint
Measures how long it takes for the largest visible element (usually a hero image, a heading, or a large block of text) to render. This is meant to approximate "when does the page feel loaded" better than older metrics like "time to first byte," which can be fast even when the page is still visually blank.
Common causes of bad LCP:
- A large hero image that isn't optimized (wrong format, no compression, no responsive sizing).
- Render-blocking CSS/JS that delays the browser from painting anything.
- Slow server response time (the page can't start rendering until the HTML arrives).
Fixes:
<img src="/hero.jpg" fetchpriority="high" alt="..." />Marking your LCP image with fetchpriority="high" tells the browser to fetch it before other, lower-priority resources. Combined with serving modern formats (WebP/AVIF) and proper srcset sizing, this is usually the highest-leverage LCP fix.
INP — Interaction to Next Paint
Replaced the older "First Input Delay" metric. INP measures the latency of all interactions throughout a page's lifetime (clicks, taps, key presses), not just the first one — capturing responsiveness across the whole visit, not a single early moment.
Common causes of bad INP:
- Long JavaScript tasks blocking the main thread when a user interacts (a heavy click handler, an expensive re-render).
- Large, unoptimized React re-renders triggered by a single state change.
Fixes: Break up long tasks (setTimeout or scheduler.yield() to yield back to the browser between chunks of work), memoize expensive computations, and avoid triggering large component tree re-renders from a single small interaction.
CLS — Cumulative Layout Shift
Measures unexpected layout movement — content jumping around as a page loads, most commonly from images or ads loading without reserved space, or fonts swapping in and reflowing text.
Common causes:
<img>tags without explicitwidth/height(oraspect-ratio), so the browser doesn't know how much space to reserve before the image loads.- Ads or embeds injected without a reserved slot.
- Web fonts that swap in with different metrics than the fallback font, shifting text.
Fixes:
<img src="/photo.jpg" width="800" height="450" alt="..." />Always specify dimensions (or aspect-ratio in CSS) so the browser reserves space immediately, before the image loads — this is precisely why this project's AdSlot component (src/components/ads/ad-slot.tsx) reserves a fixed size up front rather than sizing to content.
Where to actually check your scores
PageSpeed Insights and the Chrome DevTools Lighthouse panel both report all three metrics, and — importantly — PageSpeed Insights shows real field data from Chrome users when available (the "Field Data" section), which reflects your actual visitors' experience, not just a single lab-simulated run. Lab data (Lighthouse) is useful for debugging a specific page load; field data is what Google actually uses for the ranking signal.
The practical priority order
LCP and CLS are usually the easiest wins (image dimensions, image optimization, avoiding render-blocking resources) and often the biggest score movers. INP tends to require more invasive JavaScript profiling and is worth tackling once the more mechanical LCP/CLS fixes are in place.