Largest Contentful Paint (LCP)

What LCP measures, its thresholds, the four sub-parts that make it up, and how to actually improve it — the Core Web Vital people struggle with most.

First published: Jun 26, 2026 · Last updated: Jul 18, 2026 · Advanced
demand #3 in Web Vitals#9 in Web Performance#76 in Technical SEO#102 on the site

Largest Contentful Paint (LCP) is the render time of the largest image or text block visible in the viewport, relative to when the page started loading. Good is ≤2.5 s at the 75th percentile of real users; it's one of the three Core Web Vitals. It breaks into four sub-parts — TTFB, resource load delay, resource load duration, and element render delay — and TTFB plus load duration usually dominate. The biggest wins: don't lazy-load the LCP image, give it fetchpriority=high, preload it, cut render-blocking resources, and fix TTFB. It's a field metric — lab tools only approximate it — and of the Core Web Vitals it's the one people struggle most to pass, especially on mobile.

TL;DR — LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. is the render time of the largest image or text block visible in the viewport, relative to when the page started loading. Good is ≤ 2.5 s at the 75th percentile of real users (split by device); 2.5–4 s needs work, over 4 s is poor. It’s one of three Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. and breaks into four sub-parts — TTFBTime to First Byte — the time from the start of a request to when the first byte of the response arrives. It's a diagnostic metric (not a Core Web Vital) and a major input to FCP and LCP; ≤0.8 s is good., resource load delay, resource load duration, element render delay — where TTFBTime to First Byte — the time from the start of a request to when the first byte of the response arrives. It's a diagnostic metric (not a Core Web Vital) and a major input to FCP and LCP; ≤0.8 s is good. and load duration usually dominate (guidelines, not fixed shares — diagnose your own page). Top fixes: never lazy-load the LCP image, add fetchpriority="high" on the actual candidate, preloadResource hints are <link> elements (or equivalent HTTP Link headers) that tell the browser to do network work — DNS lookups, connection setup, or fetching a resource — earlier than it would discover the need on its own. The main ones are dns-prefetch, preconnect, preload, modulepreload, and prefetch. it when it isn’t in the HTML, kill render-blocking CSSRender-blocking resources are CSS and synchronous JavaScript files a browser must download and process before it can paint any visible content. They sit on the critical rendering path and delay First Contentful Paint and Largest Contentful Paint./JS, and fix TTFB. It’s a field metric — lab tools only approximate it — and the LCP element can change during load. Google confirms Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. feed ranking systems but doesn’t publish an exact LCP weight or call it a tiebreaker; content relevance still dominates.

What LCP actually measures

LCP reports the render time of the largest image or text block visible in the viewport, measured relative to when the user first navigated to the page. Google’s own framing: it’s the closest standardized proxy for when the main content appears to the user. It replaced earlier, fuzzier metrics like First Meaningful Paint and Speed IndexSpeed Index measures how quickly content is visually displayed during page load — the average time at which visible parts of the page appear, scored in seconds (lower is better). It's a lab-only Lighthouse metric, not a Core Web Vital and not a ranking factor..

A few things that trip people up right away:

  • It’s not “page load time.” A page can have every resource fetched and still post a slow LCP if renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. the largest element was blocked. LCP is about that one element, not the whole page.
  • It’s not the same as FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.. First Contentful Paint fires when any content first appears; LCP waits for the largest element. A page can have a fast FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. (the navbar paints) and a slow LCP (the hero image loads late).
  • It’s a dynamic metric. The browser dispatches a new LCP candidate every time a larger element becomes visible. The last entry before the user interacts (tap, scroll, keypress) or the page unloads is the value that counts — interaction often changes what’s visible, so reporting stops there. A candidate that’s later removed from the DOM doesn’t erase its own entry — it stays the reported element unless a still-larger one renders before reporting stops.

The thresholds — and why 2.5 seconds

BucketLCP
Good≤ 2.5 s
Needs improvement2.5 s – 4.0 s
Poor> 4.0 s

Assessed at the 75th percentile of real-user page loads, segmented by device type. So three out of four visits need to come in under 2.5 s for an origin to pass.

Evidence for this claim A good LCP is 2.5 seconds or less at the 75th percentile of page loads, segmented by device type. Scope: Current web.dev LCP field threshold and assessment method. Confidence: high · Verified: web.dev: Largest Contentful Paint

Why 2.5 specifically? Google’s threshold methodology leaned on two things: human perception research pointing at roughly 1–3 seconds as the band that feels “immediate,” and CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. achievability data showing 2.5 s was consistently achievable for well-optimized sites without being trivially easy. Tighter targets like 1.5 s or 2.0 s weren’t consistently achievable across enough origins, so they didn’t make the cut.

What counts as the LCP element

The element types considered for LCP:

  • <img> elements
  • <image> elements inside an <svg>
  • <video> elements (the poster image load time, or the first frame, whichever is earlier)
  • An element with a background image loaded via the CSS url() function
  • Block-level elements containing text nodes or other inline text children

The reported size is what’s actually visible in the viewport — portions clipped or scrolled off don’t count, and for images it’s the visible size or the intrinsic size, whichever is smaller. Margins, padding, and borders are ignored. A handful of elements get excluded by heuristics: anything with opacity: 0, elements that cover the whole viewport (treated as backgrounds), and low-entropy placeholder images.

About three-quarters of pages have an image as their LCP element — so image work is usually the right first move. But not always, and not always compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. (more on that next). The remaining chunk are text LCPs, where the lever is entirely different: it’s font loadingFont loading is how a browser fetches, applies, and renders custom web fonts — and specifically what it shows while the font file downloads. Those choices, controlled mainly by the CSS font-display property, directly affect two Core Web Vitals: LCP and CLS., not image weight.

The four sub-parts — the part most articles skip

This is the framework I’d start any LCP diagnosis with. web.dev breaks LCP into four sequential sub-parts:

  1. Time to First Byte (TTFB) — from when the user starts loading the page to when the browser receives the first byte of HTML. Typical share: ~40% of total LCP.
  2. Resource load delay — the gap between TTFB and the browser starting to load the LCP resource. This is discovery time. Typical share: under 10%.
  3. Resource load duration — how long the LCP resource itself takes to download. Typical share: ~40%.
  4. Element render delay — from when the resource finishes loading to when the element actually paints. Typical share: under 10%.
LCP sub-partTypical share of total LCP
Time to First Byte~40%
Resource load delay< 10%
Resource load duration~40%
Element render delay< 10%

The principle behind the table: the vast majority of LCP time should be spent loading the HTML document and the LCP resource. Any stretch where neither is loading is an opportunity to improve.

web.dev is explicit that these percentages are guidelines, not strict rules — don’t convert them into absolute-second targets, and don’t force every page to match the split. They’re only meaningful relative to each other, and if your LCP is consistently within 2.5 seconds already, the relative proportions don’t matter at all. Use the table to spot which sub-part is eating an outsized share on your page, then fix that one — not to chase an exact 40/10/40/10 split.

Evidence for this claim An LCP image should not be lazy-loaded, and reducing resource load delay is a primary LCP optimization. Scope: web.dev guidance for image-based LCP elements. Confidence: high · Verified: web.dev: Optimize LCP
Break LCP into four sequential sub-parts, then optimize the part consuming more than its intended share. Source: web.dev

The timeline begins with Time to First Byte, targeted at roughly 40 percent of total LCP. Resource load delay follows and should remain under 10 percent. Resource load duration is targeted at roughly 40 percent. Element render delay should remain under 10 percent and ends when the largest element actually paints.

© Patrick Stox LLC · CC BY 4.0 ·

And here’s the bit that upends the common assumption: as of February 2025 these four sub-parts are available in the CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. API for image LCPs, and the Chrome team’s analysis of HTTP Archive data found that image download time was often the smallest part of LCP time. In other words, “just compress my images” frequently fixes the wrong sub-part. TTFB and discovery delay are often the bigger levers.

How to find your LCP element

Before you optimize anything, find out which element is your LCP and which sub-part is the bottleneck:

  • PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. — the Diagnostics section flags the LCP element, and the field-data tab shows your real-user score.
  • Chrome DevTools — the Performance panel marks the LCP node on the timeline.
  • The web-vitals JS library — log LCP (and the element) from your own real-user monitoring.

How to improve LCP

Map each fix to the sub-part it targets:

Fix resource load delay (discovery). This is the highest-leverage and most commonly broken one.

  • Never lazy-load your LCP image. loading="lazy" on the LCP element always adds unnecessary load delay. Reserve lazy loadingLazy loading defers loading of off-screen or non-critical resources — usually images and iframes — until they're about to enter the viewport. The native way to do it is the loading=\"lazy\" HTML attribute, which needs no JavaScript. for below-the-fold images.
  • Add fetchpriority="high" to the likely LCP image so the browser fetches it early at high priority.
  • Preload it with <link rel="preload"> when the image isn’t discoverable in the initial HTML — for example, when it’s loaded via CSS or JavaScript. Loading the hero image via JS is an anti-pattern precisely because it hides the URL from the browser’s preload scanner.
  • Host critical resources on the same origin so the browser doesn’t pay extra connection setup.

Preload and fetchpriority solve different problems, so don’t reach for both by habit. Preload exposes a resource the browser’s preload scanner would otherwise discover late (a JS- or CSS-loaded image, for example); fetchpriority changes the fetch priority of a resource the browser already found. If discovery and priority are already correct — the image is a plain <img> in the initial HTML — adding either can do little beyond extra requests. Check a trace, apply the one that matches the actual problem, and confirm the field number moved.

TIP

To identify the current LCP candidate and separate field status from lab debugging, run the Core Web Vitals Checker Free

  1. Run the public page and confirm which element the fresh lab trace reports as LCP.
  2. Check whether discovery delay, load duration, render delay, or TTFB is actually the largest sub-part.
  3. Apply the matching fix, rerun the lab trace immediately, then use field data to confirm the real-user outcome.
This focused finding is a next step, not a diagnosis by itself: confirm the hero image is the LCP candidate and that discovery or transfer time is the slow sub-part before changing delivery.

The focused Core Web Vitals Checker finding says Improve the largest contentful paint and recommends optimizing and preloading the hero image, then verifying the LCP element in a fresh lab trace.

Fix element render delay.

  • Reduce or inline render-blocking CSS; defer non-critical styles.
  • Avoid synchronous scripts in the <head>.
  • Prefer server-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. or static generation so the markup arrives ready to paint, and break up long main-thread tasks.

Reduce resource load duration.

  • Modern image formatsThe file encoding used to store an image (JPEG, PNG, WebP, AVIF, SVG, GIF) — it drives file size and Core Web Vitals, but carries no direct ranking weight. (WebP, AVIF), sensible compression, and a CDN.
  • Efficient Cache-Control. And don’t ignore network contention — lazy-loading the other below-fold images can free up bandwidth so the LCP image lands sooner.

Reduce TTFB.

  • Minimize redirectsA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't., drop unnecessary unique URL parametersThe `?key=value` data tacked onto the end of a URL after a question mark — used for tracking, sessions, filtering, sorting, and search — and one of the biggest sources of duplicate URLs and wasted crawling in SEO., and optimize server response time. Note that LCP includes any unload time from the previous page, connection setup, and redirect time — all of which roll into TTFB.

Special case: text-based LCP. When the largest element is text, the critical path is font loading, not image weight. font-display: optional or system fonts eliminate font-induced render delay; font-display: swap without preloading the font file can introduce it.

Lab vs. field — this distinction matters

LCP is fundamentally a field metric. Google assesses it on real users via CrUX, surfaced in PageSpeed Insights’ field tab and the Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. Core Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. report. That field dataPerformance metrics captured from real users, not lab tests. is what feeds rankings.

Lab tools — LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal., Chrome DevTools, WebPageTestWebPageTest is a free, open-source, lab-based website performance testing tool — created by Patrick Meenan in 2008 and acquired by Catchpoint in 2020 — that runs pages on real browsers from distributed locations and produces deep diagnostics (waterfalls, filmstrips, connection views, Core Web Vitals). It's a diagnostic tool, not a Google ranking input. — only approximate it under simulated conditions, and they don’t even use the same scoring. Lighthouse applies stricter desktop thresholds (Good ≤ 1.2 s) than the field standard (≤ 2.5 s). So a passing Lighthouse score doesn’t guarantee a passing CrUX score, and vice versa. Use lab tools to debug and reproduce; trust the field data for the actual verdict.

There’s a second reason lab and field numbers can diverge, worth knowing so an odd reading doesn’t send you chasing a phantom bug: the current LargestContentfulPaint browser API (still a W3C Working Draft) is scoped to a single document load. It doesn’t itself reset on back/forward cache (bfcache) restores or same-document SPA navigations, and pages that start off-screen — background tabs, prerendered pages — can report inflated values because timing runs from load rather than from when the page actually became visible. The reporting algorithm also halts on qualifying user input, so if a user interacts before your main content displays, LCP won’t capture it. None of this changes the threshold table above; it explains why a specific session’s number can look wrong when the underlying navigation isn’t a plain first load.

Does LCP affect rankings?

Yes, in the sense that Google confirms Core Web Vitals feed its ranking systems and recommends achieving good scores. But current Search Central documentation doesn’t publish an exact LCP weight and doesn’t describe it as a tiebreaker — Google’s own framing is that page experience “can contribute to success in Search” for queries where multiple pages already offer comparable, relevant content, and that a good score doesn’t guarantee a ranking boost. Content relevance and quality still dominate. Optimize LCP because a faster-feeling page is genuinely better for users (and conversions) — not because the mechanism is documented as a rankings tiebreaker, because it isn’t.

A couple of realities from the data: of the Core Web Vitals, LCP is the one sites struggle most to improve, and it’s noticeably harder on mobile than desktop — slower CPUs and connections. On 3G and slower, the 2.5 s threshold can feel almost impossible to hit.

Where this fits

LCP is one of three Core Web Vitals, alongside Interaction to Next Paint and Cumulative Layout Shift. Its first sub-part, Time to First Byte, is its own diagnostic metric, and First Contentful Paint sits right next to it on the loading timeline. You’ll see all of these in PageSpeed Insights, Lighthouse, and the Chrome User Experience Report (CrUX). Each is its own deep dive in this cluster.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.