Understanding the LCP Struggle

You’ve just run a performance audit, and there it is—a giant red circle. You’re staring at your Core Web Vitals dashboard asking, “why is my lcp so high?” If you’re like most developers I work with, you’ve probably tried a few generic plugins and compressed some images, but the number isn’t budging.

Largest Contentful Paint (LCP) measures the time it takes for the largest visible element—usually a hero image, a banner, or a large block of text—to become visible within the viewport. In my experience, a high LCP isn’t usually caused by one single “slow” thing, but rather a chain of delays in the critical rendering path. To fix it, we have to stop guessing and start measuring.

The Fundamentals: What Actually Drives LCP?

Before jumping into the fixes, you need to understand that LCP is composed of four distinct time phases. When you ask why your LCP is high, you’re actually asking which of these four is the bottleneck:

If you aren’t sure where to start, I always recommend checking Google PageSpeed Insights vs Lighthouse to see the difference between lab data and real-user field data.

Deep Dive: The Most Common LCP Culprits

1. Slow Server Response Times (TTFB)

If your TTFB is high, every other metric suffers. I’ve seen sites where a bloated WordPress database or a poorly configured Node.js middleware adds 2 seconds to the initial request. At that point, your LCP is already failed before a single pixel is rendered.

The Fix: Implement edge caching via Cloudflare or Vercel. If you’re using a traditional VPS, ensure you have a reverse proxy like Nginx configured correctly to handle static assets.

2. Render-Blocking Resources

This is the most common reason developers ask “why is my LCP so high?” Your browser finds a large CSS file or a synchronous JavaScript bundle in the <head> and stops everything to download and parse it. The LCP image is sitting right there in the HTML, but the browser refuses to touch it until the JS is done.

<!-- ❌ BAD: Render blocking JS in head -->
<script src="/js/main-bundle.js"></script>

<!-- ✅ GOOD: Defer non-critical JS -->
<script src="/js/main-bundle.js" defer></script>

3. The “Lazy Load” Trap

Lazy loading is great for images at the bottom of the page, but it is fatal for your LCP element. If you apply loading="lazy" to your hero image, you’re telling the browser: “Don’t download this until you’re sure it’s in the viewport.” The problem is that the browser often waits until the layout is fully calculated to decide what’s in the viewport, adding massive load delay.

Comparison of LCP waterfall charts showing the difference between lazy-loaded and eagerly loaded hero images
Comparison of LCP waterfall charts showing the difference between lazy-loaded and eagerly loaded hero images

4. Font Loading and FOIT

If your LCP element is a large heading, the browser might be waiting for a custom web font to download before showing the text. This is known as Flash of Invisible Text (FOIT). To avoid this, I always suggest optimizing font loading for LCP by using font-display: swap;.

Technical Implementation: The LCP Checklist

Based on the audits I’ve performed over the last year, here is the exact sequence I use to bring a 4.0s LCP down to under 1.2s:

Step 1: Prioritize the LCP Image

Use fetchpriority="high" on your hero image. This tells the browser that this specific image is more important than other images on the page.

<img src="hero.jpg" fetchpriority="high" alt="Product Hero">

Step 2: Preload Critical Assets

If your LCP image is defined in a CSS file (like a background-image), the browser won’t find it until the CSS is downloaded and parsed. Bypass this by preloading the image in the HTML head:

<link rel="preload" as="image" href="/images/hero-banner.webp">

Step 3: Modern Image Formats

Stop using JPEGs for hero banners. WebP is the baseline, but AVIF often provides another 20-30% reduction in file size without losing quality. As shown in the benchmark analysis we’ve seen in other performance guides, the reduction in Resource Load Duration is immediate.

Guiding Principles for Long-term Performance

To prevent LCP regression, adopt these three mindset shifts:

Tools for LCP Debugging

Beyond the standard Lighthouse report, I recommend these tools for a deeper look: