Understanding Lighthouse: Largest Contentful Paint
Lighthouse says: “Largest Contentful Paint marks the time at which the largest text or image is painted.” Here’s what that means, why it matters for your SEO and users, and how to fix it.
Your hero image takes 5 seconds to show up. Your headline sits invisible while JavaScript churns away. Your users? They’ve already hit the back button. That’s the cost of a slow Largest Contentful Paint, and it’s killing your conversions and search rankings.
LCP is one of Google’s Core Web Vitals, which means it directly impacts how Google ranks your website. A slow LCP doesn’t just frustrate users, it actively hurts your SEO. Let’s figure out what Lighthouse is telling you and how to fix it.
What Lighthouse Is Telling You
When Lighthouse flags your Largest Contentful Paint, you’ll see something like this:
Largest Contentful Paint marks the time at which the largest text or image is painted.
LCP measures how long it takes for the biggest visible element on your page to render. This is usually your hero image, main headline, or featured video poster. The browser watches as elements paint to the screen and tracks whichever one takes up the most pixels in the viewport.
Lighthouse breaks LCP into four phases that add up to your total score:
- Time to First Byte (TTFB): How long until your server responds
- Load Delay: Time between TTFB and when the browser discovers the LCP resource
- Load Duration: How long it takes to actually download the LCP element
- Render Delay: Time between download completing and the element appearing on screen
Each phase is an opportunity to improve. If your TTFB is 2 seconds before anything else even starts, no amount of image optimization will save you.
Lighthouse Scoring Thresholds:
| LCP Time | Score | What It Means |
|---|---|---|
| 0-2.5s | Good (Green) | Users perceive the page as fast |
| 2.5-4s | Needs Improvement (Orange) | Noticeable delay, some users bounce |
| Over 4s | Poor (Red) | Serious problem, users are leaving |
These thresholds matter because Google uses them for ranking decisions. LCP accounts for 25% of your overall Lighthouse Performance score.
Why It Matters
Back in the early web days, we measured page performance with a simple “load” event. When the browser finished downloading everything, the page was “done.” Simple.
But modern websites don’t work that way. JavaScript frameworks render content after the initial HTML loads. Images lazy-load as you scroll. Third-party widgets inject themselves whenever they feel like it. The “load” event became meaningless because pages could feel completely usable long before it fired, or painfully slow long after.
Google created LCP to answer a better question: when does the user think the page is ready? Research showed that users perceive a page as “loaded” when they can see the main content, which is almost always the largest visible element. That hero image. That headline. That product photo.
This metric directly correlates with user behavior:
- 53% of mobile users abandon sites that take over 3 seconds to load (Google research)
- A 1 second delay in page response can reduce conversions by 7% (Aberdeen Group)
- Google factors LCP into search rankings as part of the Page Experience update
For a deeper technical dive into how LCP is measured through browser APIs, check out our guide on Measuring Largest Contentful Paint.
How to Fix It
Improving LCP means attacking those four phases: server response, resource discovery, download time, and render delay. Here’s where to focus.
1. Speed Up Your Server Response (TTFB)
Your LCP can’t be faster than your Time to First Byte. If your server takes 2 seconds to respond, your LCP is at least 2 seconds.
# Check your TTFB in the Network panel
# Or use curl to measure server response time
curl -w "TTFB: %{time_starttransfer}s\n" -o /dev/null -s https://yoursite.com
Common fixes:
- Cache your HTML with tools like Varnish, Cloudflare, or your framework’s built-in caching
- Use a CDN to serve content from servers closer to your users
- Optimize database queries if your pages are dynamically generated
- Upgrade your hosting if you’re on shared hosting with limited resources
2. Make Sure the Browser Finds Your LCP Element Early
The browser can’t load what it doesn’t know about. If your LCP image is buried in JavaScript or loaded by a CSS background, the browser discovers it late.
For images, use a preload hint to tell the browser about important resources immediately:
<head>
<!-- Tell the browser to start loading the hero image right away -->
<link rel="preload" as="image" href="/images/hero.webp">
</head>
If your LCP element is text, make sure fonts are loading efficiently. Use font-display: swap so text renders immediately with a fallback font while custom fonts load:
@font-face {
font-family: 'MyHeadlineFont';
src: url('/fonts/headline.woff2') format('woff2');
font-display: swap;
}
3. Shrink Your LCP Resource
Smaller files download faster. For images, this means:
- Use modern formats: WebP is typically 25-35% smaller than JPEG. AVIF is even smaller where supported.
- Serve the right size: Don’t send a 2000px image to a 400px container
- Compress appropriately: Quality 80-85 is usually indistinguishable from 100
<picture>
<source srcset="/images/hero.avif" type="image/avif">
<source srcset="/images/hero.webp" type="image/webp">
<img src="/images/hero.jpg" alt="Hero image" width="1200" height="600">
</picture>
For text-based LCP elements, ensure your HTML and CSS are minified and compressed with gzip or brotli.
4. Remove Render-Blocking Resources
JavaScript and CSS in your <head> can block the browser from painting anything until they’re fully loaded and parsed.
<!-- BAD: This blocks rendering -->
<script src="/js/analytics.js"></script>
<!-- GOOD: This loads without blocking -->
<script src="/js/analytics.js" defer></script>
Critical CSS that’s needed for above-the-fold content should be inlined. Everything else can load asynchronously:
<head>
<!-- Critical CSS inline -->
<style>
.hero { /* styles for LCP element */ }
</style>
<!-- Non-critical CSS loads async -->
<link rel="preload" href="/css/full.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
</head>
Common Mistakes
Lazy-loading the LCP image. Lazy loading is great for images below the fold. It’s terrible for your hero image. The browser waits for JavaScript to execute before even starting to load the image, adding hundreds of milliseconds to your LCP.
Using CSS background images for hero content. Background images aren’t discoverable until the CSS is parsed. Use an <img> tag with proper preloading instead.
Forgetting about mobile. Your LCP element might be different on mobile versus desktop. A desktop hero image might be below the fold on mobile, making your headline the LCP element instead. Test both.
Ignoring third-party scripts. That chat widget, analytics bundle, or A/B testing tool might be blocking your main content from rendering. Audit your third-party scripts and defer anything that isn’t essential for initial render.
Over-optimizing Lighthouse at the expense of real users. Remember, Lighthouse has limitations. A perfect Lighthouse score means nothing if your real users on slow networks still experience a 5-second LCP. Use Real User Monitoring to see what’s actually happening in production.
Keep Improving
Lighthouse gives you a snapshot, but your LCP changes based on network conditions, server load, and what content appears on each page. Here’s how to stay on top of it:
-
Set up Real User Monitoring to track LCP for actual visitors. Request Metrics shows you LCP broken down by page, device, and connection type.
-
Check your Core Web Vitals in Search Console. Google reports how your pages perform for real Chrome users through the Chrome User Experience Report.
-
Test after every deploy. Lighthouse scores can regress when you add new features. Include performance testing in your CI/CD pipeline.
-
Identify your actual LCP element. It might not be what you expect. Use Chrome DevTools Performance panel to see exactly which element triggers LCP on each page.
LCP is the single most impactful Core Web Vital for perceived performance. When users see your main content quickly, they trust that your site works. When they don’t, they leave. It’s that simple.