Back

Core Web Vitals: How to Optimize LCP

Core Web Vitals: How to Optimize LCP

Largest Contentful Paint (LCP) measures how quickly your main content loads—the hero image, headline, or video that visitors see first. When this takes more than 2.5 seconds, users perceive your site as slow, bounce rates increase, and your Core Web Vitals scores suffer. This guide breaks down exactly how to diagnose and fix LCP issues across all four phases of the loading process.

Key Takeaways

  • LCP measures the render time of the largest visible content element before user interaction
  • Google requires 75% of page visits to achieve LCP under 2.5 seconds for good Core Web Vitals
  • Optimization involves four phases: TTFB, resource discovery, load duration, and render delay
  • Never lazy-load above-the-fold content—it’s the most common LCP mistake

What Is Largest Contentful Paint (LCP)?

LCP tracks the render time of the largest visible content element in the viewport before user interaction. This could be an <img>, <video>, or text block. Unlike abstract metrics, LCP reflects what users actually experience—when the page “feels” loaded.

Google sets clear thresholds:

  • Good: Under 2.5 seconds
  • Needs Improvement: 2.5-4.0 seconds
  • Poor: Over 4.0 seconds

To pass Core Web Vitals, 75% of your page visits must achieve “good” LCP scores. This directly impacts SEO rankings, as Google uses Core Web Vitals as a ranking signal.

The Four Phases of LCP Optimization

LCP isn’t a single metric—it’s the sum of four distinct phases. Understanding this breakdown is crucial for targeted optimization:

  1. Time to First Byte (TTFB): Server response time (~40% of total LCP)
  2. Resource Load Delay: Time between TTFB and LCP resource download start (<10%)
  3. Resource Load Duration: Actual download time (~40%)
  4. Element Render Delay: Time from download completion to visual rendering (<10%)

The “delay” phases should approach zero. Any time spent waiting is pure waste.

Phase 1: Optimize Server Response Time (TTFB)

A slow TTFB undermines everything else. If your server takes 3 seconds to respond, achieving a 2.5-second LCP becomes impossible.

Common TTFB issues:

  • Multiple redirects (each adds 100-500 milliseconds)
  • Distant servers from users
  • Inefficient backend code
  • Database bottlenecks

Solutions:

  • Implement server-side caching
  • Use a CDN to serve content from edge locations
  • Minimize redirects—use the final URL format directly
  • Optimize database queries and backend processing

Pro tip: CDNs can mask server issues. Test with URL parameters (e.g., ?test=123) to bypass CDN caches and reveal true server performance.

Phase 2: Eliminate Resource Discovery Delays

The browser must find your LCP resource immediately. Any discovery delay is wasted time.

Critical mistake: Lazy-loading the LCP image. Never use loading="lazy" on above-the-fold content—it intentionally delays your most important element.

Make resources discoverable:

<!-- Good: Image in HTML -->
<img fetchpriority="high" src="/hero.webp" alt="...">

<!-- Bad: Hidden in CSS -->
.hero { background-image: url('/hero.webp'); }

For CSS background images (avoid these for LCP when possible), preload them:

<link rel="preload" fetchpriority="high" as="image" href="/hero.webp" type="image/webp">

The fetchpriority="high" attribute tells browsers to prioritize this resource above others. Without it, images often download with “Low” priority by default.

Phase 3: Reduce Resource Load Duration

Smaller files download faster. This phase is pure physics—reduce bytes, reduce time.

Image optimization:

  • Use modern formats (WebP, AVIF)
  • Implement responsive images with srcset
  • Compress without visible quality loss
  • Size images correctly—don’t load 4K images for mobile

Font optimization for text LCP:

  • Use font-display: swap to show text immediately
  • Subset fonts to required characters
  • Preload critical fonts

CDN considerations:

  • Image CDNs automatically optimize formats and compression
  • Same-origin serving avoids connection overhead
  • Use CDN proxy features when available

Phase 4: Minimize Render Blocking

Even with resources downloaded, rendering can stall due to main thread congestion.

Common blockers:

  • Render-blocking CSS in <head>
  • Synchronous JavaScript execution
  • Long tasks from third-party scripts

Solutions:

Inline critical CSS:

<style>
  /* Only above-the-fold styles */
  .hero { /* styles */ }
</style>

Defer non-critical JavaScript:

<script defer src="/app.js"></script>

For text-based LCP elements blocked by web fonts, ensure fallback rendering:

@font-face {
  font-family: 'Custom';
  font-display: swap; /* Shows fallback immediately */
  src: url('/font.woff2') format('woff2');
}

Special Cases: Video and Background Images

Video elements: The poster image or first frame becomes the LCP candidate. Optimize the poster image like any other image, and ensure video encoding is efficient.

CSS background images: These create inherent discovery delays. The browser can’t preload what it hasn’t parsed. Convert critical background images to <img> elements, or preload them explicitly.

Measuring and Monitoring LCP

Lab data (PageSpeed Insights, Lighthouse) helps diagnose issues, but field data (CrUX, RUM) shows real user experience. Always prioritize field data—it’s what Google uses for rankings.

Use Chrome DevTools Performance panel to see LCP breakdowns locally. The web-vitals JavaScript library enables custom monitoring:

import {onLCP} from 'web-vitals';

onLCP(({value, entries}) => {
  console.log('LCP:', value, entries[0].element);
});

Conclusion

Optimizing LCP requires systematic attention to all four phases. Start with TTFB—no optimization matters if your server is slow. Ensure immediate resource discovery, minimize file sizes, and eliminate render-blocking resources. Most importantly, never lazy-load your LCP element. With these optimizations in place, achieving a sub-2.5-second LCP becomes not just possible, but predictable.

FAQs

Lab tools like PageSpeed Insights test under controlled conditions with specific network speeds and devices. Real users have varying connections, devices, and geographic locations. Field data from CrUX reflects actual user experiences, which is what Google uses for rankings.

Yes, JavaScript frameworks can delay LCP if they render content client-side. The browser must download, parse, and execute JavaScript before displaying content. Server-side rendering or static generation can significantly improve LCP for framework-based sites.

Generally yes. Lazy loading below-the-fold images reduces initial page weight and improves performance. Just ensure you never lazy-load above-the-fold content, especially your LCP element. Use loading=lazy for images outside the initial viewport.

Third-party scripts can block the main thread, delaying both resource loading and rendering. They may also inject render-blocking resources. Load third-party scripts asynchronously, defer non-critical ones, and consider using web workers for heavy processing tasks.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay