Make Your LCP Image Load First Every Single Time
Priority hints, fetchpriority, responsive AVIF, and preload tuning that drag your hero image's load under the 2.5 second LCP line.
On most content sites and marketing pages, the thing that decides whether the page feels fast is a single image: the hero. It is usually the largest element in the viewport, which means it is usually the Largest Contentful Paint element, which means its load time is the number Google grades you on. Get that one image to paint quickly and your LCP score moves more than any amount of JavaScript trimming will.
The target is concrete: an LCP of 2.5 seconds or less for at least 75 percent of visits. The frustrating part is that the most common reason sites miss it is not slow servers or huge files, it is that the browser discovers the hero image late or treats it as low priority and downloads three analytics scripts ahead of it. Both of those are fixable with attributes you can add in an afternoon.
Find the actual LCP element first
Before optimising anything, confirm what the LCP element actually is. It is not always the obvious hero. Sometimes it is a background image, sometimes a block of text, sometimes a logo that happens to be the biggest painted thing on a sparse page. Chrome DevTools' Performance panel and Lighthouse both report the LCP element by name. Optimising the wrong image is a popular way to spend a day and move the number zero.
Once you know the element, the work splits into two distinct problems, and conflating them is why a lot of "I added fetchpriority and nothing changed" stories exist. The first problem is discovery: when does the browser find out the image exists. The second is prioritisation: once it knows, how high in the queue does it put it. Different attributes solve each one. And whatever the lab tools tell you, confirm the win against real traffic, because your Lighthouse score lies and field data tells the truth.
The single most common mistake: lazy-loading the LCP image
If you take one thing from this, take this. Never lazy-load your LCP image. Lazy loading defers an image until the browser thinks it is about to enter the viewport, which is exactly wrong for an image that is already in the viewport on first paint. It guarantees a resource load delay and tanks your LCP.
This is not a rare error. According to the 2025 Web Almanac, 16 percent of pages still lazy-load their LCP image. It usually happens because a developer added loading="lazy" to every image with a global rule or a component default, and the hero got swept up in it. Audit your hero specifically. It should have loading="eager" or no loading attribute at all, never lazy.
Fix prioritisation with fetchpriority
By default the browser does not know your hero is the most important image on the page. It assigns image priority conservatively and may let scripts and other images go first. fetchpriority="high" is the hint that tells it otherwise.
<img src="hero-1280.avif" fetchpriority="high" alt="..."
width="1280" height="720">
The impact is real and measured. The Google Flights team added fetchpriority="high" to their hero image and saw LCP improve by 700 milliseconds, and they called it the single most impactful change in their performance sprint. That kind of swing is not cosmetic, because every slow second actually costs you in revenue. Across sites monitored by one performance vendor, 82 percent of sites that use fetchpriority="high" on their LCP image pass LCP, against 61 percent that do not. That gap is the difference between passing and failing for a lot of pages.
A nuance worth knowing: fetchpriority="high" is a hint, not a command. The browser still balances it against other resources. That is usually fine, but if the image is also being discovered late, the hint alone is not enough, which brings us to preload. While you are reaching for hints, speculation rules that make navigations feel instant apply the same priority thinking to the next page rather than the current one.
Fix late discovery with preload
If your hero image is referenced inside CSS as a background, injected by JavaScript, or chosen by a responsive srcset the browser cannot evaluate until it parses the markup, the browser discovers it late. Late discovery is a delay that no priority hint can recover, because you cannot prioritise something that has not been queued yet.
Preload solves discovery. A <link rel="preload"> in the document head tells the browser to start fetching the resource immediately, before it would otherwise find it. For a responsive image, use imagesrcset and imagesizes so preload picks the same candidate the <img> would, and add fetchpriority="high" to the preload itself so it covers both problems at once:
<link rel="preload" as="image"
imagesrcset="hero-640.avif 640w, hero-1280.avif 1280w, hero-1920.avif 1920w"
imagesizes="100vw" fetchpriority="high">
The distinction to keep straight: preload affects when a resource is discovered and added to the queue, fetchpriority affects its priority once it is in the queue. Preload solves late discovery, fetchpriority solves low prioritisation. Reach for preload only when discovery is genuinely late, because an over-eager preload can steal bandwidth from other critical resources. If the image is a plain <img> in the initial markup, the parser finds it early and fetchpriority="high" on the <img> alone is usually all you need.
Make the file itself smaller without making it worse
Priority and discovery get the right image downloading first. The file's size decides how long that download takes. Two levers do most of the work.
Use a modern format. AVIF and WebP produce dramatically smaller files than JPEG at the same visual quality, with AVIF generally winning on compression. A hero that was a 400KB JPEG is often a 120KB AVIF that looks identical. Provide a fallback for the rare browser that lacks support, but lead with AVIF.
Serve responsive sizes. A phone does not need the 1920px desktop hero. With srcset and sizes, the browser downloads the candidate that fits the device, so a mobile visitor pulls the 640px file instead of the 1920px one. Smaller files download faster, and on the metered connections a lot of real users are on, this is the difference between a hero that paints in one second and one that paints in four.
Combine both and the LCP image is the right format, the right size for the device, discovered early, and prioritised high. That is the full recipe, and it is mostly attributes rather than a rebuild. Once you are serving format-switched, device-sized files, it is worth formalising the whole thing into an image pipeline that serves the perfect byte count, and pushing your CDN cache hit ratio past 95 percent so the optimised image is served from the edge most of the time.
Do not forget the bytes in front of the image
The image cannot start downloading until the browser has the HTML and is not blocked by something ahead of it. Two upstream issues are worth a quick check, because they cap how much your image optimisation can help:
- Render-blocking CSS and synchronous scripts in the head delay everything, including discovery of the hero. Defer non-critical scripts and inline only the critical CSS, which is the heart of stopping render-blocking resources from stealing your first paint. The worst offenders are usually the third-party scripts wrecking your page speed that the marketing team added without telling you.
- A slow server response (high Time to First Byte) pushes the whole timeline back. If your TTFB is already a second, no image trick gets you under 2.5, so slash time to first byte with streaming server rendering before you chase the image.
These are the unglamorous foundations, and they are part of why performance is a whole-stack concern rather than a single attribute. When we build websites that have to score well, the hero image gets this exact treatment as a default: AVIF, responsive sizes, eager loading, high priority, preloaded only when discovery is genuinely late. It is a small, repeatable checklist, and it is the highest-leverage thing you can do for perceived speed on an image-heavy page.
The checklist
For the element that is actually your LCP:
- Confirm it in DevTools or Lighthouse, do not guess.
- Remove any
loading="lazy". The LCP image is never lazy. - Add
fetchpriority="high"to the<img>. - Preload it only if it is discovered late (background image, JS-injected, complex responsive selection), using
imagesrcsetplusfetchpriority="high". - Ship it as AVIF or WebP with a fallback.
- Serve responsive sizes with
srcsetandsizesso phones get a small file. - Check that render-blocking CSS, scripts, and a slow TTFB are not capping your gains.
None of this requires a framework migration or a rewrite. It is a handful of attributes and a format swap, and it routinely drags a failing LCP under the line. If your hero is the slow part of your page and you want it gone, we can take a look.






