LCP breakdown in Lighthouse: which part to fix first
Lighthouse splits your Largest Contentful Paint into four parts. Which one to shorten first, and why they don't add up to your LCP in PageSpeed Insights.
What does LCP breakdown in Lighthouse show you?
LCP breakdown is the PageSpeed Insights and Lighthouse 13 notice that replaced "Largest Contentful Paint element". It splits the LCP of one page load into four parts, each with its own fix: waiting for the HTML, waiting before the browser requests your LCP image, downloading it, and waiting until it appears on screen. Fix the largest part first. On most sites that is the time to first byte, so start with a page cache.
Just want the quick fix? Jump to Time to first byte, Resource load delay, Resource load duration or Element render delay.
What do Resource load delay and Element render delay mean?
The notice says: "Each subpart has specific improvement strategies. Ideally, most of the LCP time should be spent on loading the resources, not within delays." Under it are the parts with their duration, then the element Lighthouse measured as your LCP on a phone screen.

My test property page with an entrance animation on the house photo. DevTools throttling puts part of the wait for the HTML under Resource load delay.
- Time to first byte: from the moment the visitor asks for the page until the first byte of the HTML arrives. A slow server, a missing page cache or a redirect makes it long.
- Resource load delay: from that first byte until the browser requests the LCP image. It is long when the browser finds the image late, such as a background in a stylesheet or an image with loading="lazy".
- Resource load duration: the download of the image, which takes longer for a large file and on a slow connection.
- Element render delay: from the end of the download until the image is on screen. The image is there, and the page waits for files in the head or for code that hides it.
When your LCP element is text, the table has two rows: Time to first byte and Element render delay. Text needs no download of its own, so everything after the first byte counts as render delay, including the wait for stylesheets and a web font. In Lighthouse 12 the same parts were called TTFB, Load Delay, Load Time and Render Delay.
The notice is red when the LCP of that page load was over 2.5 seconds, and grey when it was under. Unscored means the notice itself adds nothing to the score. LCP is 25% of the Performance score, but Google ranks on the LCP your real visitors get.
Why don't the rows add up to your LCP in PageSpeed Insights?
PageSpeed Insights loads your page once on a fast connection and then calculates what the load would take on a slow phone. The LCP under Metrics is that calculated number. In the notice, the four rows and the red or grey come from the fast load itself.

Metrics: LCP 2.9 s

LCP breakdown: 1.3 s in total
One Lighthouse run as PageSpeed Insights does it, on my test property page before any fix, without a page cache.
So in PageSpeed Insights a download looks shorter than it is on a phone, and the notice can be grey while LCP is over 2.5 seconds. A slow server and code that holds the image back still show up there. For rows that add up to the LCP, run Lighthouse in Chrome DevTools with its throttling method set to DevTools throttling, or record a trace. Values also differ between runs, so compare a few.
Which part of LCP is usually the largest?
According to the State of Web Vitals, the time to first byte is the largest part of LCP on phones on two in three sites; the image download is the largest on about one in fifty. Compressing the LCP image is the fix people try first, and on most sites it shortens the smallest part.
How much faster does LCP get with each change?
On a phone, a visitor to my test property page sees the address and the price under a white space where the photo of the house goes. Seconds later the photo fades in.

Before: the photo is downloaded, the space is white

After: the photo is on screen
The property page with the WebP photo, 2.5 seconds into the load, with and without the entrance animation.
I built a property page like an estate agent's WordPress site, with Elementor and a gallery slider, and fixed one part at a time:
| Change | LCP | Load delay | Load duration | Render delay |
|---|---|---|---|---|
| Before | 6.70 | 2.02 | 4.10 | 0.01 |
| + photo in the HTML | 4.64 | 0.01 | 4.04 | 0.01 |
| + WebP at phone size | 4.11 | 0.01 | 1.59 | 1.94 |
| + no entrance animation | 2.18 | 0.01 | 1.59 | 0.01 |
Medians of five loads, in seconds, on Slow 4G with a 4x slower CPU. Each row keeps the fixes above it. LCP is the three parts plus the time to first byte, which was 0.58 s in every row with the page cache on.
Each fix shortened its own part. Putting the first slide in the HTML, so the browser requested the photo with the HTML instead of after the slider script, took two seconds off LCP.
In the WebP row the download got 2.5 seconds shorter and LCP only 0.5 seconds: the saved time moved to Element render delay. The smaller photo arrived at 2.2 seconds, but its section had an entrance animation: Elementor hides the section until its script has run, then fades it in over 1.25 seconds, and LCP counts the photo when the fade ends. Before, the slow download finished after the script, so the photo never had to wait for it.
The download is the largest part in this table because the test connection is slow and the photo shares it with the other files; for real visitors it rarely is.
How do you see the LCP breakdown in a DevTools trace?
Record a trace in the Performance panel and open LCP breakdown in the Insights sidebar. The timeline then shows the four parts as bands under the tracks, and the LCP image's request in the Network track ends where Element render delay starts.

My test property page with the WebP photo and the entrance animation, in the Performance panel.
In Element render delay, the Main track shows the scripts that run before the paint, and the Animations track any animation; in the screenshot the photo waits 0.65 seconds for Elementor's frontend script, then "fadeIn" runs to the end of the band. For Resource load delay, click the image request: its details name the stylesheet or script that asked for it. Time to first byte and Resource load duration are the HTML request and the image request themselves: click one to see the server wait or the file size. When you set up field data (Field metrics > Set up, on the panel's start screen) and CrUX has data for your site, the insight also shows a Field p75 table with the parts for your real Chrome visitors.
How do you fix LCP breakdown?
Start with the row with the largest duration, in a run whose rows add up to the LCP: a fix on a small row barely moves LCP.
Time to first byte
On WordPress, switch on the page cache in your cache plugin (WP Rocket, LiteSpeed Cache) or at your host, so the server sends a stored copy of the page instead of building it for every visitor. Check that visitors get that copy: logged-in users, a cart cookie and a query string the cache doesn't know often skip it. On Shopify the server and its cache are Shopify's; you control the redirects, such as an old link to http or another domain. When the time to first byte stays high, a developer can find the theme's slow Liquid files with Shopify Theme Inspector for Chrome.
For a developer: cache the HTML at the CDN as well, so visitors far from your server get it from close by. Time to first byte goes through each part of the server time.
Resource load delay
The browser finds the image late. Switch off lazy loading for the first image in your plugin or theme, use an image widget instead of a section background, and make the first slide of a slider a plain image. In code, that is an <img> in the HTML without loading="lazy" and with fetchpriority="high". LCP request discovery has the steps per platform.
Resource load duration
Make the file smaller: the size the screen needs, in WebP or AVIF (an image plugin such as Imagify or ShortPixel converts them). WordPress gives images in the content and in a page builder's image widget a srcset with smaller sizes; a section background, a slider or a custom image size sends one file to every screen, so use a photo at phone size there. Shopify already sends WebP or AVIF to browsers that support it, and its current themes ask for the width each screen needs.
<img src="house-828.webp"
srcset="house-480.webp 480w, house-828.webp 828w, house-1200.webp 1200w"
sizes="100vw" width="1200" height="800" fetchpriority="high" alt="..."> Element render delay
- An entrance animation on the first screen. In Elementor, select the section or container with the photo, then Advanced > Motion Effects > Entrance Animation, and set it to None; check what sits inside it too. Page builders like Divi and WPBakery have the same setting on their sections. On Shopify, look under Theme settings > Animations: Dawn's "Reveal sections on scroll" starts its fade from almost visible, so LCP counts the image at once; in another theme, switch it off and compare Element render delay.
- A slider. Many slider scripts keep every slide hidden until they have run. Make the first slide visible in the HTML, or show one photo instead of a slider on phones.
- Delayed JavaScript. WP Rocket, Perfmatters and LiteSpeed Cache can hold scripts until the first tap or scroll. When the script that shows your photo is one of them, the photo waits for that tap. Exclude the page builder's scripts from the delay (WP Rocket's One-click exclusions, Perfmatters' Quick Exclusions), and load the page on your phone without touching it.
- An A/B test. Many client-side testing tools hide the page with an anti-flicker snippet until their script has loaded, for up to a few seconds. Run the test on the server, or test only elements below the first screen and set the tool to hide only those.
- Stylesheets and scripts in the head. The image waits for every render-blocking request. When your LCP element is text in a web font, the browser can hold the text back until the font arrives: Font display has the fix.
- Client-side rendering. A hero that only renders in the browser, such as one loaded in Next.js with
dynamic(..., { ssr: false }), waits for its JavaScript. Render it on the server so the image is in the HTML.
A fade-in from opacity 0 counts when the fade ends, so its length is added to LCP. If the photo has to fade in, start it from almost visible, as Dawn does, and run it from the stylesheet so it needs no script:
.hero {
animation: fadeIn 1s both;
}
@keyframes fadeIn {
from { opacity: 0.01; }
to { opacity: 1; }
} With Motion (Framer Motion) in React, an element with initial={{ opacity: 0 }} is in the HTML but invisible until the JavaScript has run. Give the LCP element initial={false} so it renders at its final state.
Did LCP go down, or did the wait just move?
Run Lighthouse again, with DevTools throttling so the rows add up, and compare all four rows with the run before the fix. When one row went down and another went up by about the same, the image still waits, now for something else: fix that next.
For your real visitors, open LCP in CoreDash with the device set to mobile and look at Phase breakdown: the same four parts at the 75th percentile, for image or text LCPs. Filter on the pages you changed: the part you fixed should be shorter. Field data follows the change day by day; Search Console takes up to 28 days.

Some parts you can't shorten yourself: a server you don't control, a theme or A/B tool that hides the first screen, or a wait that moves to the next row after every fix. During a Core Web Vitals power hour we open a trace of your own page and follow your LCP image from the first byte to the screen.

Need a faster site?
I'm Arjen, and I've been fixing slow sites for 17 years. If you're running into issues you can't fix yourself, send me your URL and let's have a chat.
Send me your URL
Why isn't our fix working?
Sometimes the CDN still serves the old HTML, or the fix went into the desktop template and mobile uses another one. Send me your URL and the problem, and I reply with a few times. I check your field data first, then we spend one hour on your site, and within a day you have my notes in writing. €350 excl. VAT.
Send me your URLNo developer to build the fix? I do the work myself, on a copy of your site.