A poor Largest Contentful Paint usually gets "fixed" with random tweaks: a new caching plugin, a different image format, a minifier. Sometimes that works, often it does not, because nobody checked where the time was actually going. This guide shows you how to split LCP into its four sub-parts, identify the slow one, and apply the specific fix that moves the number.
The target is an LCP of 2.5 seconds or less at the 75th percentile of real visits, measured separately on mobile and desktop. Anything over 4 seconds is rated poor. If you want the wider context first, see what LCP is in Core Web Vitals and how it sits alongside INP and CLS.
Key takeaways
- Aim for an LCP of 2.5 seconds or less at the 75th percentile, measured separately on mobile and desktop.
- Split LCP into TTFB, load delay, load duration and render delay, then fix the largest phase first.
- Never lazy load the LCP image, and give it fetchpriority high so the browser requests it straight away.
- Preload the LCP image when it is a CSS background or inserted by JavaScript, as the browser cannot discover it early.
Step 1: Find your LCP element
You cannot optimize LCP until you know which element it is. It is often not what you would guess: a cookie banner paragraph, a background image, or a large heading can all win.
Three ways to find it:
- PageSpeed Insights / Lighthouse: expand the "Largest Contentful Paint element" diagnostic. It shows the element and a breakdown of its timing.
- Chrome DevTools > Performance panel: the live metrics view shows the current LCP element as you load the page. Click it to highlight it on the page.
- Console snippet:
new PerformanceObserver((list) => {
const entries = list.getEntries();
const last = entries[entries.length - 1];
console.log('LCP:', Math.round(last.startTime), 'ms', last.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });
Check on a mobile viewport too. The LCP element on a phone is frequently different from desktop.
Step 2: Break LCP into its four sub-parts
Every image-based LCP can be split into four consecutive phases. Google's web.dev guidance suggests rough targets for each:
| Sub-part | What it covers | Rough target share |
|---|---|---|
| Time to First Byte (TTFB) | Navigation start until the first byte of HTML arrives | ~40% |
| Resource load delay | TTFB until the browser starts downloading the LCP image | under 10% |
| Resource load duration | Time spent downloading the LCP image | ~40% |
| Element render delay | Image downloaded until it is actually painted | under 10% |
These are guidelines, not rules. The point is: the two "delay" phases should be close to zero. If either is large, that is your problem, and no amount of image compression will fix it.
If the LCP element is text, there is no resource to download, so LCP is essentially TTFB plus render delay (usually caused by render-blocking CSS or web fonts).
Lighthouse's LCP diagnostic and the DevTools Performance panel both show this breakdown, so you do not need to calculate it by hand.
Fixing a slow TTFB
If TTFB alone eats most of your 2.5-second budget, start on the server:
- Cache full HTML pages so the server is not rebuilding them on every request (page caching plugin, Varnish, Nginx FastCGI cache, or CDN edge caching).
- Remove redirect chains.
http://tohttps://towwwto a trailing-slash URL can add several round trips before the real page even starts. - Watch for cache-busting query strings. Ad and email links often add unique parameters like
?gclid=or?utm_source=, which can force the CDN to skip its cache and go back to your origin. - Upgrade underpowered hosting and slow database queries.
The full playbook is in reducing TTFB and server response time.
Fixing resource load delay
This is the most common LCP problem and the cheapest to fix. It means the browser found out about your hero image late.
Make the image discoverable in the HTML
The browser's preload scanner reads raw HTML before scripts and stylesheets run. If your hero image is a plain <img> in the markup, it gets requested almost immediately. If it is:
- set as a CSS
background-image, - injected by a JavaScript slider or framework, or
- loaded via
data-srcby a lazy-loading script,
then the browser cannot see it until the CSS or JS has downloaded and run. Use a real <img> element wherever possible.
Never lazy-load the LCP image
This is a very common mistake, especially on WordPress where themes and plugins apply lazy loading to every image:
<!-- Wrong for the hero image -->
<img src="/img/hero.webp" loading="lazy" alt="...">
<!-- Right -->
<img src="/img/hero.webp" fetchpriority="high" width="1200" height="600" alt="...">
Lazy loading tells the browser to wait until layout confirms the image is in the viewport, which directly adds load delay. Keep loading="lazy" for images below the fold only.
Use fetchpriority="high"
By default, Chrome starts images at low priority and only raises them once layout shows they are visible. fetchpriority="high" lets your LCP image start at high priority straight away. It is supported in Chrome and Edge 102+, Safari 17.2+ and Firefox 132+.
<img src="/img/hero.webp" fetchpriority="high" alt="Team at work">
<img src="/img/slide-2.webp" fetchpriority="low" alt="...">
Use it on one image, maybe two. Marking everything as high priority makes it meaningless. Lowering the priority of hidden carousel slides frees bandwidth for the one that matters.
Preload images the scanner cannot see
If the LCP image must stay a CSS background or is chosen by JavaScript, preload it in the <head>:
<link rel="preload" as="image" href="/img/hero.webp" fetchpriority="high">
For responsive images, preload with the same srcset and sizes as the <img> so the browser picks the same candidate:
<link rel="preload" as="image" fetchpriority="high"
imagesrcset="/img/hero-800.webp 800w, /img/hero-1600.webp 1600w"
imagesizes="100vw">
If the image lives on a different domain (an image CDN, for example), add a preconnect so the connection is ready:
<link rel="preconnect" href="https://images.example-cdn.com" crossorigin>
Serving the LCP image from the same origin as the HTML avoids that extra connection altogether.
Fixing resource load duration
If the image starts on time but takes a long time to download, it is too heavy:
- Serve modern formats. WebP and AVIF are typically much smaller than JPEG and PNG at similar quality.
- Size it to the display. A 4000-pixel-wide photo shown at 1200 pixels wastes most of its bytes. Use
srcsetandsizesso phones get a smaller file. - Compress sensibly. Maximum quality settings waste bytes on detail nobody can see. Lower the quality until you notice artifacts on your own images, then step back up a notch.
- Use a CDN for static assets if your visitors are far from your server.
<img src="/img/hero-1200.webp"
srcset="/img/hero-600.webp 600w, /img/hero-1200.webp 1200w, /img/hero-1800.webp 1800w"
sizes="(max-width: 768px) 100vw, 1200px"
width="1200" height="600"
fetchpriority="high"
alt="Storefront at dusk">
See image optimization with WebP, AVIF and srcset for formats and tooling.
Fixing element render delay
The image is downloaded but not painted yet. Common causes:
- Render-blocking CSS and JavaScript in the
<head>. The browser will not paint anything until blocking stylesheets and synchronous scripts finish. Inline critical CSS and defer non-essential scripts. Details in eliminating render-blocking resources. - The element is hidden until JavaScript runs, such as an A/B testing tool that hides the page, or a slider that fades in its first slide. Anti-flicker snippets can add significant delay.
- Client-side rendering. If the hero is rendered by a JavaScript framework, LCP waits for the bundle to download, parse and execute. Server-side rendering or static generation helps here.
- Web fonts for text LCP. If the LCP element is a heading in a custom font with
font-display: block, text can stay invisible while the font loads. Usefont-display: swaporoptional.
Quick diagnosis cheat sheet
| Symptom in the breakdown | Fix to try first |
|---|---|
| TTFB is over half of LCP | Page caching, CDN, fewer redirects, better hosting |
| Large load delay | Remove lazy loading, use <img> not CSS background, add fetchpriority="high" or preload |
| Long load duration | WebP/AVIF, responsive srcset, compression |
| Large render delay | Critical CSS, defer JS, remove anti-flicker scripts, server-render the hero |
Frequently asked questions
Should I preload the LCP image and also set fetchpriority?
If the image is already a plain <img> in the HTML, fetchpriority="high" alone is usually enough because the browser can already discover it. Add a preload when the image is not discoverable in the initial HTML, such as a CSS background or a JS-inserted image.
My LCP element is text. What should I focus on?
Text LCP has no resource download, so focus on TTFB and render delay. That means faster server responses, removing render-blocking CSS and JS, and making sure web fonts do not hide text while loading.
Why is my LCP fine on desktop but poor on mobile?
Mobile visitors have slower CPUs and connections, and the LCP element is often a different, larger image on small screens. Check the mobile LCP element specifically and make sure phones are served an appropriately sized image.
Will a CDN fix my LCP?
It helps if TTFB or image download time is slow because visitors are far from your server. It will not fix a lazy-loaded hero image or render-blocking scripts. Check the sub-part breakdown first.
What to do next
Find your LCP element on mobile, look at the four sub-parts, and fix only the largest one before re-testing. Repeat until all the delay phases are close to zero. To check your LCP and the rest of your Core Web Vitals alongside everything else on the page, run a free audit and start with the top item on the fix list.
Related reading
- What Is a Good Page Load Time in 2026? Targets That Matter: A good page load time in 2026 means main content visible within 2.5 seconds on mobile. See the exact targets for LCP, TTFB, FCP and INP and how to hit them.
- Why Is My Website So Slow? Common Causes and How to Fix Them: Why is my website slow? Usually slow hosting, heavy images, too much JavaScript or third-party scripts. Find the real cause in minutes and fix it in order.
Sources
More guides for your industry
Free checklist (PDF)
Free health & supplement brands website checklist
30 practical checks for health & supplement brands: website speed and mobile, Google Business Profile and reviews, email security, booking and enquiry handling, and AI search visibility. Each one says why it matters, and many link to a free tool that checks it.
Written by the MakeItFlow team
We build the website audit these guides are based on. Every fact is checked against the primary sources listed above and this guide was last reviewed on 31 October 2026 . How we research and check
Check your own site in 30 seconds
Run a free audit covering speed, SEO, DNS, email authentication and security headers — and get a prioritised fix list.