What is Largest Contentful Paint (LCP)?
Largest Contentful Paint (LCP) is a Core Web Vitals metric that measures how fast the largest visible element renders on a page.
What is Largest Contentful Paint (LCP)?
Largest Contentful Paint (LCP) measures how long it takes for the biggest visible element to render in the viewport. Google made it a ranking signal in June 2021 as part of the Page Experience update. You want ≤2.5 seconds for "good," 2.5–4.0 seconds is "needs improvement," and >4.0 seconds is "poor."
Here's the catch: the metric is reported at the 75th percentile of page loads in Chrome User Experience Report (CrUX) data. That means 75% of your real users need to hit that threshold, not just your lab tests.
LCP replaced First Meaningful Paint (FMP) and Largest Meaningful Paint because those metrics were all over the place across different page types. In practice, the LCP element is usually a hero image, an above-the-fold <video> poster, or a large heading rendered with a web font. We've shipped this on 50+ projects—the LCP element is a hero image roughly 80% of the time.
How it works
The browser continuously reports LCP candidates as the page loads. Every time a larger content element finishes painting, the browser updates the LCP entry. The final LCP value locks in when the user first interacts (click, tap, keypress) or when the page fully loads—whichever comes first.
The LCP API is exposed via PerformanceObserver:
new PerformanceObserver((list) => {
const entries = list.getEntries();
const last = entries[entries.length - 1];
console.log('LCP:', last.startTime, last.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });
Eligible LCP elements include <img>, <image> inside SVG, <video> (poster image), elements with a background-image loaded via CSS, and block-level text nodes. Inline elements and zero-height elements are excluded.
What actually causes slow LCP? Four sub-parts, per Google's LCP documentation:
- Time to First Byte (TTFB) — server response latency.
- Resource load delay — time between TTFB and when the browser starts loading the LCP resource.
- Resource load duration — how long the LCP resource itself takes to download.
- Element render delay — time between resource loaded and actual paint (often caused by render-blocking CSS/JS).
Our preferred diagnostic flow: run a Lighthouse audit in Chrome DevTools, check the "Largest Contentful Paint element" diagnostic, then cross-reference with CrUX field data in PageSpeed Insights or the CrUX API.
When to use it
LCP isn't something you "choose" to use—it's measured on every page load in Chromium browsers. What you choose is how aggressively you optimize for it.
Prioritize LCP optimization when:
- Your pages rely on large hero images or video (e-commerce PDPs, landing pages, editorial sites)
- CrUX data shows >2.5s at p75—this directly affects your search ranking
- You're running paid campaigns where bounce rate matters; pages above 4s LCP see significantly higher bounce rates
- You're building a Next.js or Astro site with SSR/SSG—you have direct control over preload hints and image delivery
Deprioritize when:
- You're building a logged-in SPA dashboard (CrUX won't report it, Google won't rank it)
- Your LCP is already ≤2.0s at p75—diminishing returns kick in fast
- You're chasing lab scores instead of field data; lab-only improvements often don't move the needle
LCP vs alternatives
| Metric | Measures | Good Threshold | Status |
|---|---|---|---|
| LCP | Largest visible element render time | ≤2.5s | Core Web Vital (active) |
| FCP (First Contentful Paint) | First any content rendered | ≤1.8s | Lighthouse metric, not a CWV |
| INP (Interaction to Next Paint) | Responsiveness to user input | ≤200ms | Core Web Vital (replaced FID, March 2024) |
| TTFB | Server response time | ≤800ms | Diagnostic metric |
| Speed Index | Visual completeness over time | ≤3.4s | Lab-only, Lighthouse |
LCP and FCP get confused all the time. FCP fires the moment anything appears—a spinner, a nav bar, a background color. LCP fires when the main content finishes rendering. A page can have a fast FCP (loading skeleton in 500ms) and a terrible LCP (hero image at 5s). FCP is useful for perceived load, LCP is what Google ranks you on.
Real-world example
On a recent Astro 4 e-commerce build, our LCP element was a 1200×800 hero product image. Initial field LCP was 3.8s at p75—firmly in "needs improvement." We did four things:
- Switched from client-loaded
<img>to Astro's<Image>component withloading="eager"andfetchpriority="high". - Added a
<link rel="preload" as="image">in the<head>for the above-the-fold hero. - Served AVIF with WebP fallback via a CDN (Cloudflare Images), cutting image payload from 280 KB to 68 KB.
- Inlined critical CSS and deferred non-critical stylesheets to eliminate render-blocking.
Field LCP dropped to 1.9s at p75 within 28 days of CrUX data collection. PageSpeed Insights moved from an orange to green score, and organic click-through rate on those pages improved by 12% over the following month.