---
title: "Largest Contentful Paint (LCP): Good Scores, Fixes & Guide"
description: "LCP measures when the main content loads. Good score: ≤2.5s mobile. Fix slow LCP with image optimization, TTFB improvements, and render-blocking resource removal."
canonical_url: "https://unlighthouse.dev/learn-lighthouse/lcp"
last_updated: "2026-08-09"
---

**Largest Contentful Paint (LCP) measures when the main content finishes loading.** A good LCP score is 2.5 seconds or less on mobile (same threshold for desktop). Scores above 4 seconds are classified as poor. LCP is one of [Google's three Core Web Vitals](/learn-lighthouse/core-web-vitals) and directly affects search ranking.

<audit-impact metric="lcp">



</audit-impact>

LCP is the Core Web Vital developers struggle with most. The [Chrome UX Report shows about 40% of sites miss the recommended LCP threshold](https://web.dev/articles/top-cwv).

Why? LCP spans the full loading path: server response, resource discovery, transfer, and rendering. You need to find the slow sub-part before choosing a fix.

## What is LCP?

Largest Contentful Paint marks when the main content finishes loading. It answers the user's question: "Is this page showing me what I came for?"

The element considered "largest" changes as the page loads. The browser reports the final LCP candidate once the user interacts or the page finishes loading.

**LCP Thresholds:**

<table>
<thead>
  <tr>
    <th>
      Device
    </th>
    
    <th>
      Good
    </th>
    
    <th>
      Needs Improvement
    </th>
    
    <th>
      Poor
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Mobile
    </td>
    
    <td>
      ≤2.5s
    </td>
    
    <td>
      2.5–4.0s
    </td>
    
    <td>
      >4.0s
    </td>
  </tr>
  
  <tr>
    <td>
      Desktop
    </td>
    
    <td>
      ≤2.5s
    </td>
    
    <td>
      2.5–4.0s
    </td>
    
    <td>
      >4.0s
    </td>
  </tr>
</tbody>
</table>

**Score Weight:** LCP accounts for **25%** of your Lighthouse Performance score.

**What elements can be LCP:**

- `<img>` elements: [76% of mobile pages have an image as LCP](https://almanac.httparchive.org/en/2025/performance)
- `<video>` elements (poster image or first frame)
- Elements with CSS `background-image` via `url()`
- Block-level elements containing text: [about 24% of mobile LCP elements](https://almanac.httparchive.org/en/2025/performance)

## Why LCP matters

### User experience

Users don't wait. When the main content takes too long, they assume the page is broken. The 2.5-second mobile threshold is based on [research into user attention spans](https://web.dev/articles/defining-core-web-vitals-thresholds) - after 3 seconds, users start losing patience and bouncing.

The visual impact is immediate: a blank or skeleton screen for 4+ seconds feels broken. A fully-rendered hero in under 2.5 seconds feels fast.

### SEO impact

LCP is one of [Google's Core Web Vitals ranking factors](https://developers.google.com/search/docs/appearance/core-web-vitals). Google uses field data (CrUX) from the 75th percentile - meaning 75% of your users need good LCP for it to count as "good" for ranking purposes.

[Google describes Core Web Vitals as one part of page experience](https://developers.google.com/search/docs/appearance/page-experience). Relevance still matters more, so treat LCP as a user experience requirement rather than a shortcut to higher rankings.

### Business impact

Real-world case studies demonstrate significant revenue correlation:

<table>
<thead>
  <tr>
    <th>
      Company
    </th>
    
    <th>
      LCP Improvement
    </th>
    
    <th>
      Business Impact
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="https://web.dev/case-studies/rakuten" rel="nofollow">
        Rakuten
      </a>
    </td>
    
    <td>
      Achieved good LCP
    </td>
    
    <td>
      61% higher conversion rate
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://web.dev/case-studies/vitals-business-impact" rel="nofollow">
        Vodafone
      </a>
    </td>
    
    <td>
      31% improvement
    </td>
    
    <td>
      8% more sales
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://web.dev/case-studies/vitals-business-impact" rel="nofollow">
        Tokopedia
      </a>
    </td>
    
    <td>
      55% (3.78s → 1.72s)
    </td>
    
    <td>
      23% better session duration
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://web.dev/case-studies/vitals-business-impact" rel="nofollow">
        NDTV
      </a>
    </td>
    
    <td>
      50% reduction
    </td>
    
    <td>
      50% better bounce rate
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://web.dev/case-studies/vitals-business-impact" rel="nofollow">
        Agrofy
      </a>
    </td>
    
    <td>
      70% improvement
    </td>
    
    <td>
      76% less load abandonment
    </td>
  </tr>
</tbody>
</table>

The pattern is consistent: faster LCP correlates with better engagement and conversion.

## Start with field data

CrUX and Search Console report LCP at the 75th percentile, split by mobile and desktop. Start with the failing device group and URL pattern. Then reproduce one representative page in Lighthouse or Chrome DevTools.

Mobile-first indexing describes which page version Google crawls. It does not make desktop performance irrelevant. A slow desktop experience still affects desktop users, and CrUX reports it separately.

If URL-level CrUX data is unavailable, use origin data as context, not proof that the page passes. Low-traffic pages may have different templates and LCP elements from the home page.

## LCP sub-parts breakdown

Google recommends [breaking LCP into four sub-parts](https://web.dev/articles/optimize-lcp) to pinpoint exactly where time is being wasted:

<table>
<thead>
  <tr>
    <th>
      Sub-part
    </th>
    
    <th>
      Target % of LCP
    </th>
    
    <th>
      What it measures
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        TTFB
      </strong>
    </td>
    
    <td>
      ~40% (1.0s)
    </td>
    
    <td>
      Time for server to return first byte
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Resource Load Delay
      </strong>
    </td>
    
    <td>
      <10% (0.25s)
    </td>
    
    <td>
      Time before LCP resource starts downloading
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Resource Load Duration
      </strong>
    </td>
    
    <td>
      ~40% (1.0s)
    </td>
    
    <td>
      Time to download the LCP resource
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Element Render Delay
      </strong>
    </td>
    
    <td>
      <10% (0.25s)
    </td>
    
    <td>
      Time from download complete to painted
    </td>
  </tr>
</tbody>
</table>

These percentages are diagnostic guidelines, not fixed budgets. The two delay phases should be close to zero. TTFB and resource transfer take real network time, so they usually occupy most of a healthy LCP trace.

### Why this matters

Each sub-part has different causes:

- **High TTFB**: Server issues, no caching, redirects, slow database
- **High Load Delay**: LCP image not discoverable in HTML, blocked by scripts
- **High Load Duration**: Image too large, no CDN, slow connection
- **High Render Delay**: Render-blocking CSS/JS, large DOM, client-side rendering

Measure first, then target the right sub-part. The [2026 LCP practices guide](/learn-lighthouse/lcp/best-practices-2026) covers current Lighthouse Insights and newer browser features after you fix the basic loading path.

## Common LCP issues

Poor LCP stems from a short list of causes. Here are the most impactful:

<table>
<thead>
  <tr>
    <th>
      Issue
    </th>
    
    <th>
      Impact
    </th>
    
    <th>
      Difficulty
    </th>
    
    <th>
      Fix Time
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/slow-server-response">
        Slow Server Response (TTFB)
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Hours–Days
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/render-blocking-resources">
        Render-Blocking Resources
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Hours
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/redirects">
        Redirects
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Low
    </td>
    
    <td>
      Minutes
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/prioritize-lcp-image">
        Prioritize LCP Image
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Low
    </td>
    
    <td>
      Minutes
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/lcp-lazy-loaded">
        LCP Lazy-Loaded
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Low
    </td>
    
    <td>
      Minutes
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/resource-load-delay">
        Resource Load Delay
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Hours
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/client-side-rendering">
        Client-Side Rendering
      </a>
    </td>
    
    <td>
      High
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Hours–Days
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/large-images">
        Large Images
      </a>
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Low
    </td>
    
    <td>
      Minutes
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/lazy-loading-above-fold">
        Lazy Loading Above Fold
      </a>
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Low
    </td>
    
    <td>
      Minutes
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/total-byte-weight">
        Total Byte Weight
      </a>
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Hours
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/unminified-javascript">
        Unminified JavaScript
      </a>
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Low
    </td>
    
    <td>
      Minutes
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-lighthouse/lcp/unused-javascript">
        Unused JavaScript
      </a>
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      High
    </td>
    
    <td>
      Hours–Days
    </td>
  </tr>
</tbody>
</table>

→ [Diagnose your specific issue](/learn-lighthouse/lcp#common-lcp-issues)

## How to measure LCP

### Lab testing (development)

Lab tests give you controlled, reproducible results - but they represent synthetic conditions, not real users.

**Chrome DevTools:**

1. Open DevTools → Performance tab
2. Click record → reload page
3. Look for "LCP" marker in timeline
4. Hover to see which element and timing

**Lighthouse:**
Run an audit in DevTools or via CLI. Check the LCP metric and related audits under "Opportunities" and "Diagnostics."

**WebPageTest:**
Detailed waterfall analysis showing exactly when LCP happens relative to other resources. Use for deep debugging.

### Field data (real users)

Field data is what Google uses for ranking. It represents actual user experience.

**PageSpeed Insights:**
Enter your URL to see CrUX (Chrome User Experience Report) data. This is the [same data Google uses for ranking decisions](https://developers.google.com/search/docs/appearance/core-web-vitals).

**Google Search Console:**
The Core Web Vitals report shows which URLs pass or fail, grouped by similar pages.

**Web Vitals JavaScript Library:**

```js
import { onLCP } from 'web-vitals'

onLCP((metric) => {
  console.log('LCP:', metric.value, 'ms')
  console.log('Element:', metric.attribution.element)
  console.log('URL:', metric.attribution.url)
})
```

Send this data to your analytics for real user monitoring.

To catch regressions automatically, set up [Lighthouse CI](/learn-lighthouse/lighthouse-ci) in your deployment pipeline.

### Lab vs field discrepancy

Common: your lab score is fine but field data fails. This usually means:

- Real users have slower connections than your test
- Real users hit pages you're not testing
- Third-party scripts behave differently in production
- Caching works in lab but not for first-time visitors

Always prioritize field data over lab scores.

## Framework guides

Framework-specific optimizations for LCP:

<card-group>
<card icon="i-simple-icons-nextdotjs" title="Next.js">

Image component, automatic optimization, and App Router streaming.

</card>

<card icon="i-simple-icons-nuxtdotjs" title="Nuxt">

NuxtImage, automatic srcset, and Nitro prerendering.

</card>

<card icon="i-simple-icons-react" title="React">

Suspense boundaries, lazy loading, and SSR strategies.

</card>

<card icon="i-simple-icons-vuedotjs" title="Vue">

Async components, SSR hydration, and image handling.

</card>

<card icon="i-simple-icons-svelte" title="Svelte">

[SvelteKit](https://svelte.dev/docs/kit/introduction)
loading strategies and image optimization.

</card>

<card icon="i-simple-icons-angular" title="Angular">

NgOptimizedImage and SSR with Angular Universal.

</card>
</card-group>

## Test your entire site

Checking LCP page-by-page misses the big picture. Your homepage might pass while 200 blog posts fail. Product pages might score well except for ones with large hero images.

[Unlighthouse](/) scans your entire site and surfaces LCP scores for every page. The CLI is free and runs locally. Cloud adds scheduled monitoring and historical tracking to catch regressions before users do.

## Common myths

### "schema.org improves LCP"

**False.** Structured data (JSON-LD) helps search engines understand your content and can improve Click-Through Rate (CTR) via rich results, but it has **zero direct impact** on LCP or load times. Focus on [rendering performance](/learn-lighthouse/lcp/render-blocking-resources), not meta tags.

### "accessibility hurts performance"

**False.** Accessible sites are often faster. Semantic HTML is lighter than `div` soup. However, screen readers rely on the DOM being ready. A site with a fast LCP but blocked main thread (poor INP) creates a frustrating experience for assistive technology users. Fast LCP is the first step in digital accessibility.
