Writing

Article

How to diagnose and fix a slow LCP

Largest Contentful Paint breaks into four parts: TTFB, load delay, load duration and render delay. Find which part owns your time, then fix that one instead of guessing.

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.

  1. Time to first byte (TTFB). Navigation start until the first byte of the document arrives. Everything else waits behind this.
  2. 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.
  3. Resource load duration. How long that fetch actually took.
  4. 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:

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:

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 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.

Element render delay

The resource arrived and the pixels still are not on screen. Look for:

The order I work in

  1. Confirm which element is the LCP, on the failing form factor.
  2. Get the four-phase breakdown and find the phase that owns the most time.
  3. Fix that phase. Re-measure.
  4. 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.

Alfred Westerveld