What Is Largest Contentful Paint (LCP)?

Largest Contentful Paint (LCP) is a Core Web Vital that measures how quickly the largest visible content element renders on a page. It captures the moment when the main content of the page has finished rendering in the user's viewport — the moment when the page "looks loaded" to a human eye, not just to the network stack. Of Google's three Core Web Vitals, LCP is widely considered the most direct measure of perceived loading speed.

Where older metrics like DOMContentLoaded or load-complete fired based on technical milestones that had little to do with what the user could see, LCP was designed to reflect actual user experience. It does not care that a 2MB JavaScript analytics bundle is still downloading in the background if the hero image and headline are already on screen. Conversely, a page whose HTML arrived in 300ms but whose main image takes 6 seconds to paint has terrible LCP even though most network-level metrics would look fine.

LCP is part of Google's Core Web Vitals alongside Cumulative Layout Shift (CLS) and Interaction to Next Paint (INP). Together, they form the page experience signals that Google uses in ranking. LCP is the one most developers spend the most time fighting, because it touches everything: server performance, network path, render blocking, image optimization, font loading, and client-side hydration.

Measure your LCP now: Run a free Core Web Vitals audit on the RankNibbler homepage or use the website speed test to see your LCP time and the specific element that is painting last.

What Elements Can Be the LCP?

LCP considers the largest of these element types in the visible viewport:

On most content sites, the LCP element is the hero image, a large banner, a featured video poster, or the main headline if there is no dominant image above the fold. On e-commerce product pages, it is almost always the primary product photograph. On landing pages with lots of text, it is often the H1 or a large paragraph.

What is not counted as LCP

LCP ignores:

What Is a Good LCP Score?

Google's thresholds are based on the 75th percentile of page loads across both mobile and desktop, measured via the Chrome User Experience Report (CrUX).

LCP TimeRatingUser Experience
0 - 2.5 secondsGoodPage feels fast; users see content quickly
2.5 - 4.0 secondsNeeds ImprovementNoticeable delay; some users become impatient
Over 4.0 secondsPoorSignificant delay; high bounce risk

To be rated "Good", 75% of visits to the page must have an LCP at or below 2.5 seconds. Field data (real users in CrUX) is what counts for Google's ranking signals; lab data (single Lighthouse test) approximates it but can diverge dramatically depending on device, network, and content variations.

Why LCP Matters for SEO

LCP is the most heavily weighted of the Core Web Vitals for perceived performance, and it has a direct, measurable relationship with user behaviour. Multiple industry studies have found:

Beyond ranking directly, LCP is the most visible performance issue to both users and stakeholders. When someone says a site "feels slow", they are usually talking about LCP, not some abstract metric like Total Blocking Time. Fix LCP and people notice.

How LCP Is Measured

LCP is reported via the Largest Contentful Paint API, which emits a PerformanceEntry every time a larger content element finishes rendering. The final LCP value is the largest element rendered before the user interacts with the page or the tab is backgrounded.

Key nuances:

Common Causes of Poor LCP

1. Slow Time to First Byte (TTFB)

TTFB is the time from request to the first byte of the HTML response. Everything downstream is gated by it — the browser cannot even start parsing HTML, let alone load the LCP element, until TTFB completes. Slow TTFB is caused by:

Target: TTFB under 200ms for static pages, under 600ms for most dynamic pages.

2. Render-blocking resources

CSS and synchronous JavaScript in the <head> must finish downloading and parsing before the browser can render any pixels. A single blocking CSS file on a slow connection can add seconds to LCP even if the HTML arrived fast.

3. Large, unoptimized images

If the LCP element is an image, its size and format determine the lower bound on LCP. A 3MB JPEG hero image on a 4G connection needs several seconds just for the bytes to arrive, regardless of everything else. Use WebP or AVIF, size the image to the display size, and apply lossy compression — see how to optimize images for SEO.

4. Client-side rendering (CSR)

Single-page apps that rely entirely on JavaScript to render content have especially bad LCP. The browser receives a near-empty HTML shell, downloads megabytes of JavaScript, executes it, fetches data from APIs, and only then renders the actual page. On low-end mobile devices, this can push LCP past 10 seconds.

5. Web font loading

If the LCP element is text and uses a web font with font-display: block, the text may not paint until the font downloads. Switch to font-display: swap or optional to render the text immediately in a fallback font.

6. Lazy loading the LCP image

The loading="lazy" attribute delays image loading until the element is near the viewport. If applied to the hero image, it can add hundreds of milliseconds of delay because the browser has to do layout and viewport calculation before triggering the download.

7. Late-discovered images

Images only referenced in CSS (background images) or loaded dynamically via JavaScript are discovered late in the page lifecycle. The browser's preload scanner does not find them until the relevant CSS or JS has been parsed. That alone can push LCP by a second or more.

8. Slow third-party resources

Fonts from Google Fonts, scripts from ad networks, tag managers, chat widgets — if any of these are render-blocking, they extend LCP.

How to Improve LCP: A Developer's Playbook

Step 1: Identify your LCP element

Before fixing anything, know what you are fixing. Chrome DevTools > Performance tab, record a page load, and the LCP marker will point to the exact element. PageSpeed Insights also shows the LCP element and its timing breakdown.

Step 2: Reduce TTFB

Before you optimize the LCP element itself, shorten the time until the browser even knows it exists.

Step 3: Preload the LCP resource

Tell the browser about the LCP resource in the HTML head so it starts downloading immediately, in parallel with HTML parsing:

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

For responsive images, use the imagesrcset and imagesizes attributes:

<link rel="preload"
  as="image"
  href="/hero-800.webp"
  imagesrcset="/hero-400.webp 400w, /hero-800.webp 800w, /hero-1600.webp 1600w"
  imagesizes="(max-width: 600px) 400px, 800px"
  fetchpriority="high">

Step 4: Use fetchpriority="high" on the LCP image

Available since Chrome 101, the fetchpriority attribute boosts the priority of the image in the browser's fetch queue. For the LCP element, it can shave hundreds of milliseconds:

<img src="/hero.webp" width="1200" height="630" alt="Hero banner" fetchpriority="high">

Step 5: Never lazy-load the LCP image

If the LCP image is in the initial viewport, it must load eagerly. Do not add loading="lazy" to above-the-fold images. You can lazy-load everything below the fold.

Step 6: Optimize image size and format

Step 7: Reduce render-blocking resources

Every blocking CSS or synchronous script in the head extends LCP. Techniques:

Step 8: Optimize web fonts

Step 9: Consider server-side rendering or static generation

If you are on a client-side rendered SPA with poor LCP, moving to SSR (Next.js, Nuxt, Remix, SvelteKit) or SSG can transform LCP. The HTML is fully rendered server-side, so the browser can show content as soon as the HTML arrives — no waiting for JS to hydrate.

Step 10: Use a CDN for images

Image CDNs like Cloudflare Images, Imgix, Cloudinary, and Bunny.net automatically resize, compress, and serve images in the best format for the user's device — often cutting image bytes by 70%+ and shaving seconds from LCP.

The LCP Breakdown: Four Sub-Phases

Google's team recommends thinking of LCP as four sub-parts. Optimizing each one independently is the most systematic way to improve LCP.

Sub-PhaseWhat It MeasuresTarget
TTFBServer response time< 200-600ms
Resource load delayTime between TTFB and when the LCP resource starts downloading< 0ms ideally
Resource load timeTime to download the LCP resourceAs short as bandwidth allows
Element render delayTime between resource arriving and element painting< 0ms ideally

Each sub-phase has distinct optimizations. A long resource load delay usually means the resource is not preloaded or not discovered by the preload scanner. A long element render delay suggests render-blocking CSS or font issues.

LCP in Code: Real Patterns

Pattern 1: Hero image optimized correctly

<!-- In <head> -->
<link rel="preload"
  as="image"
  href="/hero-1200.webp"
  imagesrcset="/hero-800.webp 800w, /hero-1200.webp 1200w, /hero-1800.webp 1800w"
  imagesizes="100vw"
  fetchpriority="high">

<!-- In <body>, near the top -->
<img
  src="/hero-1200.webp"
  srcset="/hero-800.webp 800w, /hero-1200.webp 1200w, /hero-1800.webp 1800w"
  sizes="100vw"
  width="1200"
  height="630"
  alt="Summer sale banner"
  fetchpriority="high">

Pattern 2: Inline critical CSS

<head>
  <style>
    /* 14KB of critical above-the-fold CSS inlined here */
    body { margin: 0; font-family: system-ui, sans-serif; }
    .hero { min-height: 500px; background: #111; color: #fff; }
    /* ...etc... */
  </style>
  <link rel="preload" href="/main.css" as="style" onload="this.rel='stylesheet'">
</head>

Pattern 3: Deferred non-critical JS

<script src="/analytics.js" defer></script>
<script src="/chat-widget.js" async></script>
<script type="module" src="/app.js"></script> <!-- modules are deferred by default -->

Tools to Measure LCP

PageSpeed Insights

Google's PageSpeed Insights at pagespeed.web.dev shows both lab (Lighthouse) and field (CrUX) LCP for any public URL. The Opportunities section pinpoints LCP issues with specific element and timing breakdowns.

Lighthouse in Chrome DevTools

Open DevTools, run a Lighthouse audit. The Performance section highlights LCP and shows the element, its timing, and what contributed to the delay.

Chrome DevTools Performance Panel

Record a page load, look for the LCP marker in the timings lane. Click it for the LCP element and full timing sub-phases. Indispensable for deep debugging.

Web Vitals Chrome Extension

Lightweight overlay showing LCP, CLS, and INP as you browse. Free and open source from Google.

Search Console Core Web Vitals report

Aggregates CrUX data for your verified domain, groups URLs by CWV status. Shows how many URLs have "Poor" LCP in your index.

web-vitals library

The web-vitals JavaScript library from Google sends real-user LCP data from your visitors to your analytics endpoint. Essential for ongoing monitoring:

import { onLCP } from "web-vitals";
onLCP((metric) => {
  navigator.sendBeacon("/rum", JSON.stringify(metric));
});

RankNibbler performance tools

Run any URL through the RankNibbler website speed test for LCP, CLS, INP and a list of fixes. The full audit layers in image optimization checks, render-blocking detection, and script loading analysis.

LCP in Popular Frameworks

Next.js

The <Image> component from next/image auto-generates responsive srcsets, serves modern formats, and applies priority prop to preload. For the LCP image: <Image src="/hero.jpg" width="1200" height="630" alt="..." priority />

React + Vite

Use standard <img> with preload in the HTML head. Consider vite-imagetools or vite-plugin-image for build-time optimization.

Nuxt

<NuxtImg> component does automatic optimization and responsive srcsets. For LCP: add preload and fetchpriority="high".

WordPress

Since WordPress 6.3, priority loading is automatic for above-the-fold images. Use plugins like Perfmatters, WP Rocket, or FlyingPress for critical CSS inlining and lazy-load control. Offload images to a CDN for best results.

Astro

The <Image> component handles responsive images; use loading="eager" and fetchpriority="high" on the LCP element. Astro's zero-JS default is a huge LCP advantage.

Common Mistakes That Tank LCP

LCP vs Other Core Web Vitals

MetricMeasuresGood ThresholdMain Fix
LCPLoading speed of largest element≤ 2.5sOptimize LCP element, reduce TTFB, preload
CLSVisual stability≤ 0.1Reserve space for dynamic content
INPInteraction responsiveness≤ 200msBreak up long main-thread tasks

Case Study: Cutting LCP from 5.2s to 1.8s

An e-commerce site selling outdoor gear had a field LCP of 5.2s on product pages — deep in the "Poor" range. After audit:

Remediation:

  1. Switched hero from CSS background to HTML <img> with width/height
  2. Converted to WebP at 85% quality and served responsive srcset (400/800/1600px widths)
  3. Removed lazy-load attribute, added fetchpriority="high"
  4. Added <link rel="preload" as="image" ...> in head
  5. Moved all third-party scripts to async/defer
  6. Self-hosted fonts with font-display: swap
  7. Added Redis cache for product queries, bringing TTFB to 180ms

Result: field LCP dropped to 1.8s over 28 days. Conversion rate rose 18% on the affected pages; organic traffic rose 12% as Google upgraded the page experience signal.

Monitoring LCP in Production

Lab data from Lighthouse is a single snapshot under controlled conditions. Real users vary in device, network, cache state, geography, and time of day. You need real-user monitoring (RUM).

Basic web-vitals integration

import { onLCP } from "web-vitals/attribution";
onLCP((metric) => {
  const body = {
    name: metric.name,
    value: metric.value,
    rating: metric.rating,
    element: metric.attribution.element,
    url: metric.attribution.url,
    loadTime: metric.attribution.lcpResourceEntry?.duration,
  };
  navigator.sendBeacon("/rum", JSON.stringify(body));
});

Attribution data

The web-vitals/attribution module gives per-metric breakdowns — which element was the LCP, what resource it loaded, how long each sub-phase took. This lets you spot regressions precisely.

RUM services

SpeedCurve, DebugBear, Calibre, Sentry, New Relic Browser, Akamai mPulse all offer LCP monitoring with alerts and per-page dashboards. Essential at scale.

Frequently Asked Questions

What is a good LCP score?

2.5 seconds or less is rated "Good" by Google at the 75th percentile.

Is LCP a Google ranking factor?

Yes. LCP is part of Core Web Vitals, which Google uses as a page experience ranking signal.

How is LCP different from First Contentful Paint (FCP)?

FCP measures when the first piece of content appears (could be a small logo or placeholder). LCP measures when the largest content element appears — a much closer proxy for "page feels loaded".

Why does my LCP vary between tests?

Lab tests simulate one environment; real users vary enormously. Field data from CrUX aggregates 28 days of real visits and is what Google uses for ranking.

What is the biggest single LCP improvement I can make?

Identify your LCP element (usually the hero image), preload it, remove lazy-load, and compress it aggressively. That combination is often 40-60% of total LCP wins.

Can I lazy-load the LCP image?

No. Lazy-loading the LCP image adds significant delay. Only lazy-load images below the fold.

Does LCP include time on the server?

Yes. TTFB is a sub-component of LCP, so slow server response directly increases LCP.

Does the LCP element change during page load?

It can. As larger elements render, the LCP entry updates. The final value recorded before user interaction is the reported LCP.

How do I find my LCP element?

Chrome DevTools > Performance > record a page load > look at the timings lane for the LCP marker. Or use PageSpeed Insights, which shows the element directly.

Is LCP the same on mobile and desktop?

The calculation is the same, but results differ because mobile devices are slower, viewports are smaller (different element may be largest), and networks are often slower. Google uses mobile field data primarily for mobile-first indexed sites.

Do iframes count as LCP elements?

The iframe container can be the LCP element, but its internal content is not evaluated separately.

Should I use <picture> element for the LCP image?

Yes, when art direction matters (different crops at different breakpoints). For simple responsive images, srcset on <img> is sufficient and works well with preload.

How quickly do LCP improvements show in Search Console?

Field data in CrUX is a 28-day rolling window. Meaningful changes take 4-6 weeks to fully reflect. Lab data reflects changes immediately.

LCP Sub-Phase Deep Dive

To improve LCP systematically, understanding which sub-phase dominates your measurement is critical. A 4-second LCP with 3 seconds of TTFB is an entirely different problem from a 4-second LCP with 2 seconds of load time and 0.5s TTFB.

Diagnosing long TTFB

If TTFB is over 600ms for most visits, server-side work is your bottleneck. Common diagnostics:

Diagnosing long resource load delay

The gap between TTFB and when the LCP resource starts downloading. Ideal: near zero. Common causes of delay:

Diagnosing long resource load time

The actual download. Bottlenecks:

Diagnosing long element render delay

The gap between resource arrival and element paint. Causes:

LCP and the Soft Navigation Problem

Traditional LCP measurement stops at first paint of the largest element on initial page load. Single-page apps that navigate without full page reloads (React Router, Next.js client-side nav, etc.) do not trigger a new LCP measurement by default. The W3C is actively developing the Soft Navigations API to address this — Chrome already emits soft-navigation LCP entries experimentally. Monitor this space if you run an SPA; the metric will become measurable in production RUM tools over the next year.

LCP Optimization for AMP Pages

Accelerated Mobile Pages (AMP), while declining in usage since Google removed the "AMP required for Top Stories" requirement in 2021, still exists. AMP pages have built-in LCP optimizations:

These produce excellent LCP by default — typically under 1 second on mid-range connections. If you maintain AMP alongside your canonical HTML, the AMP version often provides a usable CWV benchmark for your LCP target.

LCP in Single-Page Apps

SPAs built with React, Vue, Angular, or Svelte are traditionally LCP weak points because of the JavaScript waterfall: HTML -> JS download -> JS parse/execute -> data fetch -> render. Modern patterns that address this:

Server-side rendering (SSR)

Render initial HTML on the server, then hydrate on the client. Frameworks: Next.js, Nuxt, SvelteKit, Remix. LCP benefits because meaningful content is present in the initial HTML.

Static site generation (SSG)

Render HTML at build time, serve from CDN. Fastest possible LCP because HTML is pre-cached at edge locations. Frameworks: Next.js, Astro, Gatsby, 11ty, Hugo, Jekyll.

Streaming SSR

Send HTML in chunks as the server renders, so the browser can start painting before the entire page is ready. React 18 Suspense + Next.js App Router support this natively.

Islands architecture

Ship only the JavaScript needed for interactive "islands" within otherwise-static HTML. Astro popularized this; Qwik takes it further with resumable hydration. LCP benefits from minimal JS shipping.

Partial hydration

React Server Components and similar approaches run code on the server without shipping it to the client. Reduces the JS bundle and improves LCP for content-heavy pages.

LCP for High-Traffic Images

The LCP image is often your most-viewed asset. Optimizing it thoroughly pays off at every page load:

Optimal image formats

Use <picture> with <source type="..."> to serve the most efficient format each browser supports:

<picture>
  <source type="image/avif" srcset="/hero.avif">
  <source type="image/webp" srcset="/hero.webp">
  <img src="/hero.jpg" width="1200" height="630" alt="Hero" fetchpriority="high">
</picture>

Responsive images

Serve different sizes for different viewports:

<img
  src="/hero-1200.webp"
  srcset="/hero-400.webp 400w, /hero-800.webp 800w, /hero-1200.webp 1200w"
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 80vw, 1200px"
  width="1200"
  height="630"
  alt="Hero banner"
  fetchpriority="high">

Progressive rendering

Progressive JPEGs render as low-res placeholders and sharpen as more bytes arrive. Useful on slow connections — though LCP uses final paint, not first paint, so progressive only helps perceived speed, not the metric itself.

Placeholder strategies

Placeholders improve perceived speed but the LCP metric cares about the final content paint, not the placeholder.

LCP and HTTP/2 / HTTP/3

Modern HTTP protocols materially improve LCP on most real-world networks:

HTTP/2

HTTP/3 / QUIC

Most CDNs (Cloudflare, Fastly, CloudFront) support HTTP/3 transparently. Check that your origin or CDN has it enabled — it typically cuts LCP 5-15% on mobile networks for zero code change.

LCP Regression Prevention

Optimizing LCP once is easy; keeping it optimized forever is hard. Sites regress when teams ship new code, third-party vendors add scripts, or content editors upload un-optimized images. A prevention program needs:

Performance budgets

Define hard limits per page: maximum JS bundle size, maximum image size for LCP element, maximum TTFB. Fail builds or deployments that exceed them.

Continuous lab testing

Lighthouse CI on pull requests. Catch performance regressions before merge.

Real-user monitoring

web-vitals library plus your analytics. Alert when p75 LCP crosses 2.5s on key pages.

Image upload pipelines

CMS-integrated automatic image compression and format conversion. Content editors should not be able to upload a 10MB photo and have it served as-is — your pipeline should downsize, compress, and convert automatically.

Third-party script governance

Review each new tag in your tag manager for performance impact. Require async/defer. Reject synchronous scripts in the head unless business-critical.

Regular audits

Monthly or quarterly, review the full LCP performance of top landing pages. New issues emerge as content and code evolve.

LCP and AI Overviews

Google's AI Overviews and other AI-generated SERP features may cite your content as a source. Fast LCP is one of the signals used when Google chooses which sources to pull for generative answers — slow, heavy pages are cited less often, presumably because they would add latency to the user's experience if they click through. Fast pages both rank better and get cited more in AI features, compounding the benefits of optimization.

LCP on E-Commerce Product Pages

Product pages are the highest-value, highest-churn pages on e-commerce sites. Poor LCP directly costs revenue — studies consistently find 7-10% conversion lift per second of LCP improvement.

Product image optimization

Product images are typically the LCP element. Optimize aggressively: WebP/AVIF, responsive srcset, preload the primary image. Lazy-load the remaining gallery images.

Personalization without LCP cost

Personalization (recently viewed, recommended products, user-specific pricing) often inflates TTFB or injects content late. Render personalization client-side after initial LCP, not server-side before it. The initial page should be cacheable and fast; personalization layers over after first paint.

Third-party reviews and social proof

Trustpilot widgets, Yotpo reviews, etc. frequently block rendering. Ensure they load async and do not appear above the LCP element. If reviews must appear above the fold, render stub review data server-side and enhance with JavaScript later.

A/B testing without LCP cost

Classic A/B test scripts (Optimizely, VWO) run synchronously in the head to avoid flicker — terrible for LCP. Modern server-side or edge-rendered A/B testing (Vercel Edge, LaunchDarkly server-side) avoids the client-side tax entirely.

Final Thoughts

LCP is where page performance meets real user perception. It is the metric most directly tied to "does this page feel fast?" — the question every user implicitly asks within the first second of landing on your site. Optimizing it pays dividends in conversions, engagement, and rankings that few other changes can match.

The playbook is mature: reduce TTFB, preload the LCP resource, use modern image formats, avoid lazy-loading above the fold, and eliminate render-blocking resources. Apply those systematically, measure field data with web-vitals and PageSpeed Insights, and you will clear the 2.5s threshold on most pages.

Pair LCP work with attention to CLS and overall page speed, plus solid on-page SEO fundamentals, and you build a site that performs well for both users and search engines.

Find your LCP bottleneck: The RankNibbler audit and website speed test identify your LCP element, show the full timing breakdown, and list the specific fixes that will move the metric most.

Last updated: March 2026