Largest Contentful Paint is the time from navigation start until the largest image or text block in the viewport is painted. Google’s published threshold for “good” is 2.5 s at the 75th percentile, with anything over 4 s counted as poor.
Most advice about fixing LCP is a list of tactics — compress your images, use a CDN, preload the hero. All of those are real, and most of them will do nothing for you, because they each address a different part of the metric and only one part is usually the problem. So diagnose first.
The four sub-parts
LCP decomposes into four consecutive phases. They add up to the whole metric with no gaps, which is what makes the breakdown so useful.
- Time to first byte (TTFB). Navigation start until the first byte of the document arrives. Everything else waits behind this.
- Resource load delay. From TTFB until the browser starts fetching the LCP resource. This is dead time: the browser knew about the document but had not yet discovered, or was not yet allowed to start, the thing that becomes the LCP element.
- Resource load duration. How long that fetch actually took.
- Element render delay. From the resource finishing until it is painted on screen.
If the LCP element is a text block rather than an image, there is no resource to fetch, so phases 2 and 3 collapse and the time lives in TTFB and render delay — usually render delay, caused by a render-blocking stylesheet or a webfont.
Getting the breakdown
In Chrome DevTools, the Performance panel records a load and marks the LCP event; the Insights sidebar gives you the phase breakdown and names the element. Lighthouse has an “Largest Contentful Paint element” audit that tells you which node was chosen, which is the first thing you need to know and the thing people most often assume rather than check.
Two things to confirm before you optimise anything:
- Which element is it, on the form factor that is failing? The largest element in a 390 px viewport is frequently not the largest in a 1440 px one.
- Is that element even worth being the LCP? Sometimes the answer is that a giant decorative background or a cookie banner has been elected LCP, and the fix is to change the page, not the delivery.
What moves each part
TTFB
Slow TTFB is a server and network problem, and no amount of image work will hide it. The usual causes, in the order they are worth checking:
- No caching in front of the origin. A page rendered per-request that could
be cached, or a CDN that is passing through because of a
Cache-Controlheader nobody meant to send. - Distance. An origin in one region serving a global audience, with no edge in between.
- Slow server work. Database queries, N+1s, uncached API calls on the render path.
- Redirect chains. Every hop before the real document is pure TTFB.
http://tohttps://towww.to the canonical path is three round trips before any useful byte moves.
Static generation is the blunt instrument here and it works: if the HTML can be built ahead of time and served from an edge cache, TTFB stops being a variable.
Resource load delay
This is the phase people forget exists, and it is often the largest one. The symptom is a gap between the document arriving and the hero image request starting. Causes:
- The image is not in the initial HTML. If it is injected by JavaScript, set as a CSS background, or lives inside a client-rendered component, the browser’s preload scanner cannot find it while parsing, so the fetch starts late.
loading="lazy"on the LCP image. Lazy-loading the hero is a common own goal — it defers precisely the request you need earliest. Lazy-load below the fold, never above it.- Bandwidth contention. The hero is competing with scripts and fonts for a constrained connection.
The fixes are about discoverability and priority: put a real <img> in the
served HTML, add fetchpriority="high" to the LCP image, and use
<link rel="preload"> when the URL is genuinely not discoverable from the markup.
Note that fetchpriority="high" is a raise in priority, not a queue jump past
the round trips in front of it — it does not repair a fetch that starts two
seconds late for structural reasons.
Resource load duration
Now, and only now, does the classic image advice apply.
- Serve modern formats. AVIF or WebP over JPEG/PNG.
- Serve the right dimensions.
srcsetandsizesso a phone is not downloading a desktop-width file. - Cut the bytes. The single biggest win on most sites is a hero image that was exported at full resolution and never resized.
- Use the same origin, or preconnect. A hero served from a third-party host
pays DNS, TCP and TLS before the first byte of the image;
<link rel="preconnect">gets that handshake started early.
Element render delay
The resource arrived and the pixels still are not on screen. Look for:
- Render-blocking CSS. The browser will not paint until the CSS it needs is parsed. Split what is not needed for the initial view.
- Fonts, when the LCP element is text. A font-blocking period leaves the text
invisible;
font-display: swaporoptionalpaints something immediately, and preloading the font file shortens the window. - Hydration gating the paint. If the element only appears after a JavaScript framework has booted, your LCP includes your bundle download, parse and execution. Server-render the above-the-fold content.
- Long tasks. A busy main thread cannot paint. The same work that ruins INP will hold up LCP.
The order I work in
- Confirm which element is the LCP, on the failing form factor.
- Get the four-phase breakdown and find the phase that owns the most time.
- Fix that phase. Re-measure.
- Repeat — because fixing the dominant phase usually promotes a different one, and sometimes elects an entirely different LCP element.
That last point is the one worth internalising. LCP is not a single lever. It is a chain, and shortening the longest link just makes some other link the longest.
Lab numbers make this loop fast because they are reproducible. Field data is what finally confirms it. My published case study quotes a lab run on the Lighthouse 12 mobile preset — protectorguardrail.com at 1.7 s, measured on 5 August 2026. Getting there meant finding which of the four parts owned the time, which is exactly the situation this article describes.