Core Web Vitals
Also Known As
TL;DR
Explanation
Core Web Vitals are a subset of Web Vitals chosen by Google because they best correlate with real user perception of page quality. LCP (Largest Contentful Paint) measures how fast the main content loads — target under 2.5s. INP (Interaction to Next Paint, replaced FID in March 2024) measures responsiveness to all user interactions — target under 200ms. CLS (Cumulative Layout Shift) measures visual stability — target under 0.1 (unexpected layout shifts that frustrate users). The critical distinction: Lighthouse measures lab performance (simulated conditions); Chrome User Experience Report (CrUX) measures field performance (real users). Google's ranking signal uses field data, not lab scores — a page can score 95 in Lighthouse and still fail Core Web Vitals in the field due to real user device and network conditions.
Common Misconception
Why It Matters
Common Mistakes
- Optimising only for Lighthouse scores while ignoring CrUX field data — real users on mid-range Android devices on 4G often have dramatically worse scores.
- Lazy-loading the LCP image — the largest above-fold image must load immediately; lazy loading it is the single most common LCP regression.
- Late-loading content above existing content — ads, cookie banners, and embeds injected after load cause CLS if they push down visible content.
- Heavy JavaScript event handlers — long-running JS on click or touch delays INP even if the page loads quickly.
- No explicit image width and height — browser cannot reserve space, images load and shift content (CLS).
Avoid When
- Do not use Lighthouse as the sole measure of Core Web Vitals compliance — lab data does not reflect real user conditions.
- Do not lazy-load above-fold images in the name of performance — it directly harms LCP.
When To Use
- Use Core Web Vitals as the primary performance benchmark for any public-facing web page.
- Measure field data in CrUX or PageSpeed Insights as the authoritative source — not Lighthouse lab scores.
- Prioritise LCP fixes first (loading), then CLS (layout stability), then INP (interactivity).
Code Examples
<!-- LCP regression: lazy loading the hero image -->
<img src="hero.jpg" alt="Hero" loading="lazy">
<!-- CLS regression: no image dimensions -->
<img src="product.jpg" alt="Product">
<!-- CLS regression: content injected above existing content -->
<script>
// After load, inject banner at top of page
document.body.insertBefore(banner, document.body.firstChild);
</script>
<!-- LCP fix: eager + high priority -->
<img src="hero.jpg" alt="Hero" fetchpriority="high" loading="eager"
width="1200" height="600">
<!-- CLS fix: explicit dimensions + lazy for below-fold -->
<img src="product.jpg" alt="Product" loading="lazy"
width="400" height="400">
<!-- CLS fix: reserve space for injected content -->
<div style="min-height: 60px">
<!-- Banner loads here without shifting content -->
</div>