Optimize images for Core Web Vitals and LCP
You've optimized your images, added lazy loading everywhere, and your LCP score is still bad. What if it was precisely the lazy loading that's the problem? Most errors on image-related Core Web Vitals don't come from forgotten compression, they come from an attribute applied in the wrong place.
10 min read
En résumé
To improve Core Web Vitals related to images: convert your hero image to WebP or AVIF, explicitly add width and height attributes to prevent CLS, and use fetchpriority='high' on your main LCP image. Never use loading='lazy' on an image visible without scrolling, it's the error that most degrades LCP.
What to remember
- ✓ The LCP image is often the largest visible image at load, identify it before any optimization.
- ✓ loading='lazy' on the LCP image directly penalizes the score: the most frequent error.
- ✓ WebP reduces weight by 25 to 35% vs JPEG, but without fetchpriority, the gain remains partial.
- ✓ Explicit width and height on all images eliminate CLS from deployment.
- ✓ PageSpeed Insights distinguishes field data (CrUX) from lab measurements (Lighthouse), both count.
What Google really measures: LCP, CLS, INP and the role of images
Core Web Vitals are three metrics Google uses to evaluate a page’s user experience. Images affect two directly.
LCP — Largest Contentful Paint
Time elapsed before the largest visible element on the page is displayed. In most cases, this element is an image. Google considers an LCP ≤ 2.5 seconds as 'good'.
Aussi appelé : Largest Contentful Paint, time to render the largest element
Ex : On a page with a hero image at the top, LCP measures time before this image is fully displayed on screen.
CLS — Cumulative Layout Shift
Measure of unexpected visual movements during loading. An image whose dimensions aren't declared pushes content downward when it displays. Google considers CLS ≤ 0.1 as 'good'.
Aussi appelé : Cumulative Layout Shift, visual stability
Ex : An article whose images lack width/height declarations jumps visually during load, each arriving image pushes text down.
INP (Interaction to Next Paint) measures responsiveness to clicks and inputs, images affect it marginally, except if their decoding mobilizes the main thread for several hundred milliseconds. For reasonably-sized images, this remains marginal.
In practice: nearly all image-related Core Web Vitals problems concentrate on LCP and CLS. These are the two metrics to prioritize.
Identify your LCP image: the first step often skipped
Before optimizing anything, you need to know which image Google is watching. It’s not always obvious.
In PageSpeed Insights, the “Diagnostics” section identifies the LCP element and indicates its load delay. In Chrome DevTools, the Performance tab displays the LCP marker and highlights the element in the DOM after analysis.
The LCP image is most often:
- The hero photo at the top on a brochure site
- The first product image on an e-commerce product page
- A banner or main illustration on a blog article
If your page has no image above the fold, the LCP element can be a text block, in which case image optimizations will have limited LCP impact.
Knowing this element changes priority order. Not all page images deserve the same treatment: the LCP image deserves particular attention the others don’t.
Format and compression: the real impact of WebP and AVIF on LCP
A lighter file downloads faster. A faster download contributes to lower LCP. The link is direct, but insufficient alone.
WebP reduces a photo weight by 25 to 35% compared to JPEG at visually equivalent quality. AVIF goes further (35 to 50% reduction depending on content), but its browser support remains below WebP.
2.5 s
'Good' LCP threshold per Google
Google web.dev — Core Web Vitals
97 %
WebP browser support in 2026
Can I Use — May 2026
~94 %
AVIF browser support in 2026
Can I Use — May 2026
❌ Idée reçue
Converting images to WebP alone improves LCP.
✅ Réalité
WebP reduces file weight, and a lighter file downloads faster. But if the image isn't discovered early by the browser (no preload) or if loading='lazy' is active, the format gain is canceled by resource discovery delay. Format and loading are two independent variables.
Source : Google web.dev — Optimize LCP
In practice: converting the LCP image to WebP lossy is a good step, not a complete solution. It must be combined with loading techniques from following sections to have measurable score impact.
For concrete conversions — tools, recommended quality thresholds, special cases — our image format guide JPEG, PNG, WebP covers details by use case.
Explicit dimensions: two attributes that eliminate CLS
CLS caused by images has one root cause: the browser doesn’t know the image dimensions before downloading it. It displays surrounding content, then when the image arrives, it pushes everything that follows.
The solution is two HTML attributes:
<img src="hero.webp" width="1200" height="630" alt="Description" />
width and height let the browser calculate image ratio and reserve the corresponding space before download. Content doesn’t move. CLS drops to zero on these images.
For responsive images that change size per screen, CSS property aspect-ratio serves the same purpose:
img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}
These two attributes (width + height in HTML, or aspect-ratio in CSS) are the quickest fix to deploy on an existing site. CLS impact is immediate.
loading=“lazy”: when it’s an error (and which images to avoid it on)
loading="lazy" is a useful instruction for images below the page: it defers their download until they approach the viewport. Fewer requests at initial load, page feels lighter to the browser.
The problem: many developers apply it to every image without exception. Including the hero image, which is the LCP element.
loading='lazy' on the LCP image: the most expensive mistake
If your hero image or first product image has loading=“lazy” attribute, you’re asking the browser to defer the load of the element Google prioritizes. The browser waits for the image to be in the viewport, but it is from the first instant. The artificial delay translates directly to degraded LCP.
The rule is simple: loading="lazy" suits images below the fold: ones the user won’t see without scrolling. On all images visible without scroll (above-the-fold), the attribute is counterproductive.
In practice: remove loading="lazy" from your identified LCP image. Leave it on all other images not immediately visible.
fetchpriority and preload: preload your LCP image to gain decimals
The browser loads resources in an order it determines alone. By default, images aren’t priority — it starts with HTML, critical CSS, then JavaScript before attending to images. The LCP image can thus wait several hundred milliseconds before download.
fetchpriority="high" changes this order: it tells the browser this resource is critical and should download as priority.
Preload the LCP image: implementation
- 1
Identify the LCP image in PageSpeed Insights
Run an analysis on your page. In 'Opportunities' or 'Diagnostics' section, PageSpeed Insights identifies the LCP element and its exact URL. Note the exact file path.
In Chrome DevTools > Performance tab, click 'Record' then reload the page, the LCP marker appears on the timeline with the element highlighted.
- 2
Add fetchpriority='high' to the img tag
On the <img> tag for your LCP image, add the fetchpriority='high' attribute. Remove loading='lazy' if present. This single attribute can reduce LCP by several hundred milliseconds on mobile network.
Don't apply fetchpriority='high' to multiple images, the signal loses effectiveness if too many elements are marked priority.
- 3
Add preload to <head> for images loaded via CSS
If the LCP image is loaded via CSS (background-image) instead of <img> tag, the browser only discovers it after parsing and applying the stylesheet. A <link rel='preload'> in the <head> anticipates this delay.
Example: <link rel='preload' as='image' href='/hero.webp' fetchpriority='high' />
- 4
Verify impact in PageSpeed Insights
Rerun analysis. Compare LCP before and after in both columns: field data (CrUX) and lab data (Lighthouse). Lab change is immediate — field change takes 28 days Chrome UX Report collection.
If LCP stagnates, verify the image is actually served from a CDN or fast hosting, server TTFB (Time to First Byte) can be the limiting factor.
fetchpriority is available since Chrome 101, Firefox 132 and Safari 17.2. On older browsers, the attribute is simply ignored, no risk of regression.
Responsive images: srcset and sizes to serve the right format to the right screen
A smartphone displays your hero image on 390 pixels wide. Without srcset, it downloads the same image as the 1920px monitor — potentially 4 to 6 times heavier than necessary.
srcset declares multiple image versions at different resolutions:
<img
src="hero-800.webp"
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1600.webp 1600w"
sizes="(max-width: 768px) 100vw, 50vw"
width="800"
height="450"
fetchpriority="high"
alt="Image description"
/>
sizes tells the browser which width the image will occupy per screen size, before it renders the page. Without sizes, the browser assumes the image is 100% of window width and can download unnecessarily large version.
In practice: for the LCP image, offering three variants (400 px, 800 px, 1600 px) covers nearly all mobile, tablet and desktop cases. Variant generation happens upstream — on export or via image pipeline.
Measure and validate: PageSpeed Insights, Lighthouse, CrUX — reading the right numbers
PageSpeed Insights displays two data types on the same page. The distinction matters.
Field data (CrUX): collected on real Chrome users visiting your URL. They reflect your audience reality: mobile connections, varied devices, cache full or empty. This data impacts Google ranking.
Lab data (Lighthouse): synthetic measurement simulating a mobile device on slow connection. Useful to diagnose and compare before/after, but not representative of field reality.
Google Search Console > “Core Web Vitals” Report groups field data URL by URL on 28-day rolling window. It’s the panel to watch after deploying fixes — changes don’t appear there before several weeks of collection.
Lighthouse is the debugging tool, CrUX is the final measure. Optimizing to 100 in Lighthouse without improving CrUX is possible, and vice versa. Both metrics have their role.
Frequently asked questions
What's LCP and why do images affect it? ▾
How do I know which image is my LCP image? ▾
Does switching to WebP automatically improve Core Web Vitals? ▾
Is loading='lazy' always a good practice? ▾
What's fetchpriority='high' and why use it? ▾
How do images cause CLS? ▾
What's the difference between Lighthouse data and field data in PageSpeed Insights? ▾
Compress and convert your images to WebP directly in the browser
100% local, free, no account. No image leaves your device.
Try Impmage
GlitchGhost
Independent developer
Developer specializing in web performance and image optimization. Creator of Impmage.
On the same topic
JPEG, PNG, WebP: which format compresses best for your use?
Decision table by use case to choose the right format.
8 min
Compress an image without losing quality: methods, formats and settings 2026
Quality thresholds, tools and use cases for compression without degradation.
8 min
Images and SEO in 2026: the practical guide to rank better
Alt, naming, structured data and Core Web Vitals: essentials for image SEO.
9 min