Largest Contentful Paint (LCP)
Also Known As
TL;DR
Explanation
LCP marks the point in the page load timeline when the largest visible content element in the viewport finishes rendering — typically a hero image, featured image, or large heading. It is Google's primary measure of perceived load speed because it correlates strongly with users' sense of 'the page has loaded'. Target: under 2.5s (Good), 2.5-4s (Needs Improvement), over 4s (Poor). The LCP element is determined at render time — it can change as the page loads (a small image renders first, then a larger image loads and becomes the LCP). Common causes of slow LCP: the LCP element is an image that loads late (especially when lazy-loaded or in a carousel); render-blocking CSS or JS delays page rendering; the server response is slow (high TTFB); the LCP image is not preloaded or doesn't have fetchpriority='high'; web fonts block text rendering. LCP is measured in field data (CrUX) — real user values often differ significantly from Lighthouse lab simulations.
Common Misconception
Why It Matters
Common Mistakes
- Lazy-loading the LCP image — loading='lazy' on the hero image delays it and is the single most common LCP regression.
- No fetchpriority='high' on the LCP image — browser doesn't know this image is critical and may deprioritise it.
- LCP image not discovered in HTML — image in CSS background or loaded by JavaScript is discovered late, after the browser could have started downloading it.
- Render-blocking resources delaying all rendering — scripts and stylesheets in <head> without defer/async delay the point at which any image can begin rendering.
- High server TTFB — if the HTML itself takes 2s to arrive, LCP cannot be under 2.5s regardless of other optimisations.
Avoid When
- Do not lazy-load the LCP element — ever.
- Do not rely on Lighthouse lab scores as the sole LCP benchmark — field data is what Google uses for ranking.
When To Use
- Measure LCP in CrUX field data as the authoritative source — Lighthouse lab scores regularly understate real user LCP.
- Use Chrome DevTools Performance panel to identify the LCP element and trace its load waterfall.
- Prioritise TTFB improvement if server response is slow — no amount of image optimisation can overcome a 2s server response.
Code Examples
<!-- LCP image lazy-loaded — the single biggest LCP mistake -->
<img src="hero.jpg" alt="Hero" loading="lazy">
<!-- LCP image with no priority hint -->
<img src="hero.jpg" alt="Hero">
<!-- LCP image in CSS — not discovered in HTML scan -->
<style>
.hero { background-image: url('/hero.jpg'); }
</style>
<!-- LCP image: eager, high priority, preloaded, with dimensions -->
<head>
<!-- Preload the LCP image for earliest possible download -->
<link rel="preload" href="/hero.jpg" as="image" fetchpriority="high">
</head>
<body>
<img src="/hero.jpg" alt="Product launch team"
fetchpriority="high"
loading="eager"
width="1200" height="600"
decoding="sync"><!-- sync ensures it renders in first frame -->
</body>