- core-web-vitals
- performance
How images affect Largest Contentful Paint, and what to change
Images are the LCP element on most pages. See where LCP time goes, why image download time is rarely the bottleneck, and which HTML changes load it sooner.
By Focal team 6 min read
Largest Contentful Paint (LCP) measures when the largest image, text block or video in the viewport finishes rendering, counted from the moment the user started the navigation. Google rates an LCP of 2.5 seconds or less as good and anything over 4 seconds as poor, measured at the 75th percentile of page loads. On most pages the LCP element is an image. This post breaks LCP into its four parts, shows field data on where the time goes, and lists the HTML changes that move an image’s LCP the most.
Images are the LCP element on most pages
The 2025 Web Almanac found an image as the LCP element on 85.3% of desktop pages and 76% of mobile pages. The same chapter reports that 74% of desktop pages and 62% of mobile pages have a good LCP.
web.dev lists the elements that can count as LCP:
<img>elements, using the first frame of an animated image<image>elements inside an<svg><video>elements, using the poster image or the first frame- elements with a background image loaded through
url() - block-level elements that contain text
For images, the browser counts the smaller of the visible size and the intrinsic size. A 400-pixel image stretched to fill 1200 pixels counts as 400 pixels wide. Chromium-based browsers also skip elements that cover the full viewport, elements with zero opacity, and low-entropy placeholder images.
The four parts of LCP
web.dev splits every image LCP into four consecutive parts:
- Time to First Byte (TTFB) runs from the start of the navigation until the first byte of the HTML arrives.
- Resource load delay runs from TTFB until the browser starts downloading the LCP image.
- Resource load duration is the time the image download takes.
- Element render delay runs from the end of the download until the image renders.
On a well-optimised page, web.dev suggests roughly 40% of LCP for TTFB, under 10% for load delay, roughly 40% for load duration and under 10% for render delay. The two parts with “delay” in their names should be close to zero.
Download time is rarely the bottleneck
A web.dev analysis of Chrome field data looked at page loads where the LCP element was an image. For each origin it took the 75th percentile of each part, then reported the median across origins:
| Origin’s LCP rating | TTFB | Image load delay | Image load duration | Render delay |
|---|---|---|---|---|
| Good | 600 ms | 350 ms | 160 ms | 230 ms |
| Needs improvement | 1,360 ms | 720 ms | 270 ms | 310 ms |
| Poor | 2,270 ms | 1,290 ms | 350 ms | 360 ms |
Image load duration is the shortest part in every row. The authors found that most origins with a poor LCP spend less than 10% of their 75th-percentile LCP time downloading the image. The median poor origin waits 1,290 ms before it even starts the download, almost four times as long as the download itself.
Smaller images still help. The larger gains usually come from making the browser request the image earlier.
Put the image in the HTML
The browser’s preload scanner reads the HTML as it arrives and starts requests for the resources it finds there. web.dev’s LCP guide says the scanner can find an <img> only when its src or srcset is in the initial HTML. It lists three patterns that hide the image:
- an
<img>that JavaScript adds to the page - a lazy-loading library that keeps the URL in
data-srcordata-srcsetuntil its script runs - a CSS background image
<!-- Found only after the lazy-loading script runs -->
<img data-src="/hero-1280.jpg" class="lazyload" alt="Living room with oak furniture">
<!-- Found while the browser parses the HTML -->
<img src="/hero-1280.jpg" width="1280" height="640" fetchpriority="high"
alt="Living room with oak furniture">
Do not lazy-load it
The web.dev LCP guide warns against lazy-loading the LCP image in any case. A lazy image waits until layout confirms it is in the viewport, which adds load delay every time. The 2025 Web Almanac found that about 16 to 17% of pages still lazy-load their LCP image, and 10.4% of mobile pages do it with the native loading="lazy" attribute. Check whether your framework or content management system (CMS) adds that attribute to every image by default.
Raise its fetch priority
Browsers do not fetch images at the highest priority, because images do not block rendering. web.dev’s Fetch Priority article describes Chrome’s behaviour. Images start at low priority, and Chrome raises in-viewport images to high only after layout. Since Chrome 117, the first five large images start at medium priority.
The fetchpriority="high" attribute moves the image up before layout happens. Chrome and Edge support it from version 102, Firefox from 132 and Safari from 17.2. In a test on Google Flights, adding it to the LCP background image improved LCP from 2.6 seconds to 1.9 seconds. The 2025 Web Almanac found it on 17% of mobile pages that have an LCP image.
Set it on one image, or two at most. web.dev notes that marking more images as high priority stops helping LCP.
Preload only what the browser cannot find
When the LCP image comes from CSS or from a script, a preload link tells the browser about it early. Include fetchpriority="high", because a preload otherwise gets the default low priority for images. For a responsive image, imagesrcset and imagesizes work like srcset and sizes.
<link rel="preload" as="image" fetchpriority="high"
href="/hero-1280.jpg"
imagesrcset="/hero-640.jpg 640w, /hero-1280.jpg 1280w, /hero-2560.jpg 2560w"
imagesizes="100vw">
web.dev recommends the <link> element for responsive preloads, not an HTTP Link header, because the viewport is not known when the headers arrive. If the image is already in the HTML as an <img>, skip the preload and use fetchpriority on the element.
Account for a second origin
A browser has to open a new connection before it can download from an origin it has not used yet. The 2025 Web Almanac found that 16 to 18% of pages load their LCP image from a different host than the page. web.dev calls same-origin hosting the best option and a preconnect hint the next best. MDN explains that preconnect performs the Domain Name System (DNS) lookup, the Transmission Control Protocol (TCP) connection and the Transport Layer Security (TLS) handshake ahead of time.
<link rel="preconnect" href="https://img.example.com">
Then reduce the bytes
Load duration was still 350 ms for the median poor origin, so cut it once you have fixed the delays. web.dev lists four ways:
- Reduce the file size with the right dimensions, a modern format and sensible compression.
- Reduce the distance with a content delivery network (CDN).
- Reduce contention by not loading many other large files at the same time.
- Remove the network time for repeat visits with a long cache lifetime.
Watch for render delay while you do this. web.dev shows a page that hides its LCP element until JavaScript finishes. On that page a faster download only moved time from load duration into render delay.
Using Focal for the LCP image
Focal serves images from img.focaltool.com, and Focal does not offer custom domains. For your pages, that means the LCP image always comes from a second origin. Add a preconnect hint for https://img.focaltool.com near the top of the <head>, keep the <img> URL in the HTML, and set fetchpriority="high" on it. Focal resizes the image from the URL, serves WebP to browsers that accept it when the URL names no format, and caches the result at the edge. The Focal docs show the URL format.
To find your own bottleneck, record a performance trace in Chrome DevTools and open the LCP breakdown in the Insights panel. If resource load delay is more than 10% of your LCP, the browser is finding the image late or fetching it at low priority. Fix that before you touch the compression settings.
Sources
- web.dev, Largest Contentful Paint (LCP)
- web.dev, Optimize Largest Contentful Paint
- web.dev, Common misconceptions about how to optimize LCP
- web.dev, Optimize resource loading with the Fetch Priority API
- web.dev, Preload responsive images
- HTTP Archive, Web Almanac 2025, Performance chapter
- MDN, rel=“preconnect”