How to optimize the image behind your LCP
On most pages the Largest Contentful Paint element is a single image: the hero, the product shot, the banner at the top. If that image is heavy, sized wrong, or told to wait, your Core Web Vitals suffer no matter how fast the rest of the page is. Google's web.dev documentation is blunt about the biggest lever: “Ensure the LCP resource is discoverable from the HTML source and prioritized.” Four choices decide whether your LCP image helps or hurts: its format, its declared size, when the browser finds it, and whether you accidentally deprioritized it.
The symptom: a big beautiful image that arrives last
You added a strong hero image, and your speed score dropped. That is not a coincidence. The moment the largest visible element is an image, that image is the metric. A 900KB JPEG discovered halfway down the page load can single-handedly push LCP past the 2.5-second line Google documents as the threshold for a good experience, even on a site that is otherwise lean.
The tell shows up in PageSpeed Insights: the LCP element it names is your hero image, and its "load delay" or "resource load time" is the largest slice of the LCP breakdown. That is the browser telling you the image was found late or downloaded slowly. Both are fixable in the HTML.
The cause: four image choices, and usually two are wrong
- Wrong format. A raw JPEG or PNG carries far more bytes than it needs. WebP and AVIF hold the same visual quality at a fraction of the size, and every current browser supports WebP.
- No declared dimensions. An image with no
widthandheightforces the browser to guess, which both slows layout and causes the shift problem that hurts a second vital. - Late discovery. If the image URL only appears after a stylesheet or a script runs, the browser cannot start fetching it early. It waits, and so does your LCP.
- Self-inflicted lazy-load. The most common mistake we see in real scans: the above-the-fold hero carries
loading="lazy". That attribute tells the browser the most important image on the page can wait. It should never be on the LCP element.
The fix: format, size, priority, in that order
Start by cutting the bytes, then make sure the browser finds and prioritizes what is left.
- Export the hero as WebP (or AVIF with a WebP fallback). This alone often halves the file.
- Serve the right size for the device with
srcset, so a phone never downloads a desktop-width image. - Always set
widthandheightso the browser reserves the space and can plan the layout. - Preload the LCP image and mark it high priority, and never lazy-load it.
<!-- Found early, fetched first --> <link rel="preload" as="image" href="/hero.webp" fetchpriority="high" /> <img src="/hero-800.webp" srcset="/hero-800.webp 800w, /hero-1600.webp 1600w" sizes="(max-width: 800px) 100vw, 800px" fetchpriority="high" width="1600" height="900" alt="What the page is about" /> <!-- loading="lazy" belongs only on images below the fold --> <img src="/further-down.webp" loading="lazy" width="800" height="450" alt="..." />
The broad, four-lever version of this fix, covering server response and render-blocking resources as well as the image, lives in our guide on fixing a slow Largest Contentful Paint. This page is the image-specific deep cut of that same problem.
Be honest: bytes are not the whole story
Two cautions. First, a perfectly optimized image on a page that renders nothing without JavaScript still fails, because the image is discovered late no matter how small it is. If that is your situation, the real fix is in making the page render without JavaScript. Second, an image with declared dimensions helps LCP and also prevents layout jump, so getting this right pays into a second vital at the same time. The full picture of that second one is in what causes Cumulative Layout Shift.
Verify: name the LCP element, then re-measure
Run your URL through PageSpeed Insights and confirm two things: the named LCP element is the image you optimized, and its load delay collapsed. If you are not sure how to read that report, we walk it plainly in how to read PageSpeed Insights. Then check it against the hub: run a Core Web Vitals audit on your site to see LCP beside INP and CLS. Field data updates on a rolling 28-day window, so a fix today shows up over weeks, while the lab section confirms the mechanism moved today.
Then read it the way a crawler does. Paste your link into our GEO audit or the full AuditLamp audit and we tell you whether your largest image is even present in the raw HTML, plus the rest of what a machine sees. The wider fix library covers the failures speed alone cannot solve.