Largest Contentful Paint (LCP): Definition, Thresholds, Fixes
LCP is a Core Web Vital that measures when the largest visible element finishes rendering. ≤ 2.5s = good. The single biggest perceived-loading metric.
What is Largest Contentful Paint (LCP)?
Largest Contentful Paint (LCP) is a Core Web Vital that measures the time between when a page starts loading and when the largest visible content element (image, video poster, or block of text) finishes rendering. It's the metric Google uses to capture "is this page perceived as fast?" — because the largest above-the-fold element is what users actually see and judge speed by.
LCP replaced older proxy metrics like First Meaningful Paint (FMP) and Speed Index because it correlates better with real user perception of load speed. It's one of three Core Web Vitals (with INP and CLS) that Google uses as a search ranking signal.
What counts as the LCP element?
The browser inspects all visible content in the viewport and picks the largest by rendered area. Eligible elements:
<img>elements<image>elements inside an<svg><video>with a poster image- Elements with a CSS
background-imageloaded viaurl() - Block-level elements containing text nodes (text counted as a block)
The LCP element can change as more content loads. Browsers report the latest one until the user interacts with the page (which freezes LCP).
LCP thresholds
| LCP | Rating |
|---|---|
| ≤ 2.5s | Good |
| 2.5s - 4.0s | Needs Improvement |
| > 4.0s | Poor |
Reported as 75th percentile across users — a page passes only if 75% of real-user experiences are ≤ 2.5s.
What contributes to LCP time
LCP is the sum of four sub-phases (per Google's RAIL model):
| Phase | Description | Typical share |
|---|---|---|
| Time to First Byte (TTFB) | Server response time | ~10-40% |
| Resource load delay | Time before LCP resource starts downloading | ~10-40% |
| Resource load duration | Time the LCP resource takes to download | ~10-40% |
| Element render delay | Time between resource ready and rendered to screen | ~10-30% |
To optimize LCP, attack whichever phase is dominant on your page. Google's PageSpeed Insights breaks this down per page.
How to measure LCP
JavaScript API
// Capture LCP in real user sessions
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('LCP:', entry.startTime, 'element:', entry.element);
}
}).observe({ type: 'largest-contentful-paint', buffered: true });Tools
| Tool | Type |
|---|---|
| Lighthouse / PageSpeed Insights | Lab + field (CrUX) |
| Chrome DevTools Performance Panel | Lab, frame-by-frame |
| Web Vitals Chrome Extension | Field, real browsing |
| web-vitals.js | RUM, programmatic |
| Search Console CWV report | Field, your real users |
| CrUX Dashboard | Field, public per-origin |
Common LCP optimizations
1. Preload the LCP image
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">
<link rel="preload" href="/hero-mobile.webp" as="image" media="(max-width: 600px)">2. Use modern image formats
AVIF or WebP at quality 70-80 produces files 30-50% smaller than JPEG. Smaller file = faster download = lower LCP.
3. Set fetchpriority="high" on the LCP image
<img src="hero.webp" alt="Hero" fetchpriority="high" width="1200" height="675">4. Reduce TTFB
Server response time caps how fast LCP can ever be. CDN cache, faster server, edge SSR.
5. Eliminate render-blocking resources
Blocking CSS and synchronous JS in <head> delay rendering. Defer non-critical CSS; use defer / async on scripts.
6. Inline critical CSS
Above-the-fold styles in a <style> tag inside <head> render immediately without waiting for external CSS.
7. Self-host fonts + preload them
<link rel="preload" href="/inter.woff2" as="font" type="font/woff2" crossorigin>8. Avoid lazy-loading the LCP element
Counter-intuitive, but loading="lazy" on the hero image hurts LCP because the browser delays the fetch.
LCP vs other paint metrics
| Metric | What it measures | Status |
|---|---|---|
| FP (First Paint) | Anything painted (often blank background) | Diagnostic only |
| FCP (First Contentful Paint) | First text/image rendered | Diagnostic, in Lighthouse |
| FMP (First Meaningful Paint) | Old proxy for "page useful" | Deprecated 2020 |
| LCP (Largest Contentful Paint) | Largest above-fold element rendered | Core Web Vital ✓ |
| TTI (Time to Interactive) | When page is reliably interactive | Diagnostic, often unreliable |
Common LCP pitfalls
- Lazy-loading the hero image. Browser delays fetch; LCP slow.
- Heavy JavaScript blocking render. Even if image loads fast, render delay holds back LCP.
- Web fonts blocking text render. Use
font-display: swaporoptional. - Slow TTFB. If your server takes 1s+, LCP can never be < 2.5s.
- Hero image too large. 4MB hero on mobile = bad LCP. Resize + compress + use AVIF/WebP.
- CSS Background-image LCP element. Browsers can't preload these — slower than
<img>. - Hydration delay on SSR sites. JS hydration during LCP window steals CPU from rendering.
FAQ: Largest Contentful Paint
What's a good LCP score?
≤ 2.5 seconds at the 75th percentile of users. 2.5-4s = needs improvement, > 4s = poor. Sites passing this threshold get a Core Web Vitals ranking advantage.
How is LCP different from FCP?
FCP (First Contentful Paint) = first text or image rendered (often a logo or nav). LCP = the LARGEST visible element rendered (usually the hero image). LCP correlates better with perceived load speed.
How do I find which element is my LCP?
Chrome DevTools → Performance tab → Web Vitals overlay. Or use the JS API to log entry.element on the LCP entry.
Why is my LCP slow on mobile but fast on desktop?
Mobile devices have slower CPUs, slower networks (4G vs WiFi), and smaller viewports (different LCP element). Test with throttled mobile profile in Lighthouse.
Does lazy-loading hurt LCP?
If you lazy-load the LCP element (hero image): yes, badly. Use loading="lazy" only for below-the-fold content. Eager-load + fetchpriority="high" for hero.
Can I improve LCP without changing my hero image?
Yes. Reduce TTFB (CDN/cache), defer JS, inline critical CSS, preload key resources. Fontless render-blocking is a common culprit too.
What replaced FID with INP — does that affect LCP?
FID → INP swap (March 2024) was about responsiveness, not load speed. LCP is unchanged. Both LCP + INP + CLS are now the three Core Web Vitals.
Test LCP from real regions with LoadFocus
LoadFocus runs Lighthouse audits from 25+ global regions, surfacing how LCP varies by geography + network. Sign up free at loadfocus.com/signup.
Related LoadFocus Tools
Put this concept into practice with LoadFocus — the same platform that powers everything you just read about.