Largest Contentful Paint is the Core Web Vitals metric for when the biggest visible thing finishes rendering. A failing score tells you that took too long. It does not tell you which element it was, and it does not tell you which part of the process was slow — which is why so much time gets spent compressing images on pages where images were never the problem.
Which element is your LCP element?
Whichever one the browser judged largest in the initial viewport, and it is frequently not the one you would guess. Open Chrome DevTools, run a Performance trace with the page reloaded, and look for the LCP marker on the timeline. Hovering it names the element.
Two things surprise people here. A block of text can be the LCP element, so a slow-loading web font can fail the metric on a page with no large images at all. And the element can change between devices, because the viewport determines what counts as largest — the mobile LCP element is often not the desktop one.
You cannot fix LCP without naming the element first. Every optimisation applied to something that is not the LCP element is work that will not move the score.
Which of the four phases is slow?
LCP decomposes into four phases, and each has a different fix. This is the step that turns a number into a task.
| Phase | What it covers | Usual fix |
|---|---|---|
| Time to first byte | Server thinking and network latency before anything arrives | Caching, origin response time, edge delivery |
| Resource load delay | Gap between the HTML arriving and the browser starting to fetch the element | Preload, remove discovery blockers, stop lazy-loading it |
| Resource load time | Actually downloading the image or font | Smaller file, better format, correct image sizing |
| Render delay | Element downloaded but not yet painted | Unblock rendering, cut main-thread work |
Compressing an image only helps the third phase. If the trace shows most of the time sitting in resource load delay, a smaller file changes nothing — the browser had not started fetching it yet.
Why is the browser starting so late?
Usually because the element is not discoverable in the initial HTML. A hero image set through CSS, injected by JavaScript, or served through a carousel is invisible to the browser's preload scanner, so the fetch cannot begin until much later in the process.
Three self-inflicted versions of this are common enough to check first:
loading="lazy"on the hero image. Lazy loading is correct below the fold and actively harmful on the LCP element.- The image referenced only in a stylesheet, so it cannot be fetched until the CSS is parsed.
- Render-blocking resources in the head delaying everything behind them.
Lazy-loading every image sitewide because it improved a lab score once. Applied to the LCP element it delays the exact thing the metric measures.
Why does the lab score disagree with the real one?
Because they measure different things. Lab tools load the page once on simulated hardware. The score Google uses comes from field data collected from real visits on real devices, aggregated over 28 days, reported at the 75th percentile.
That last detail matters more than the rest. Passing at the 75th percentile means three quarters of visits were fast enough — so a page that is fine for most visitors and terrible on older phones can fail while looking healthy in a lab run on a fast connection. When lab and field disagree, field is the one that counts, and the gap is usually a device or network segment you did not test.
What order should you work in?
Establish the element, then the phase, then the fix. Every step skipped costs you a change that does not move the number.
- Confirm the page genuinely fails in field data, not just in a lab tool.
- Identify the LCP element on mobile specifically, since that is where most failures live.
- Break the time into the four phases and find the largest one.
- Make one change addressing that phase, then re-measure.
Field data updates on a rolling window, so a fix deployed today will take weeks to show fully. Confirm the change worked in the lab first, then wait for the field to confirm it at the percentile that counts.
Open a trace on your slowest template and name the LCP element before you touch anything. Most performance work fails at that first step, not at the fix.
Failing Core Web Vitals and not sure where to start?
We will identify the element, the phase, and the specific change that moves it, rather than handing you a list of generic performance advice.
Get in Touch →Does this apply to your site?
Reading about it is one thing. Point the scan at your own site and see whether this applies to you, and what it is worth fixing.
Free and unlimited. No account, no card, and you get every finding rather than a teaser.