Image Optimization
How to optimize images for SEO and performance — modern formats like WebP and AVIF, compression, correct dimensions, and lazy loading — to improve Core Web Vitals and LCP.
Image optimization is a speed discipline, not a ranking lever. Formats (WebP, AVIF), compression, and correct sizing exist to shrink bytes and improve LCP — there's no direct ranking boost for the format itself (Mueller confirmed this three separate times). The single highest-value rule: never lazy-load your LCP image (usually the hero) — it delays the exact metric you're trying to fix. That one gets loading="eager" plus fetchpriority="high". Native loading="lazy" is for images outside the initial viewport, not a fixed 'below the fold' line. Compression has no universal "right" quality — test per image. Correct size = rendered container size × device pixel ratio, and that container size itself moves with responsive layout, which is why you deliver a srcset range. None of this guarantees a passing Core Web Vitals score, a ranking change, or more traffic — measure LCP and CLS before and after. This is the how-to companion to the Image SEO hub, which owns the what/why.
TL;DR — Image optimization means making your pictures smaller so pages load fast, without making them look bad. Use a modern format like WebP, compress the file, and don’t serve a picture that’s way bigger than it shows on screen. The one rule people break most: the big image at the very top of your page should load right away — never “lazy loadLazy loading defers loading of off-screen or non-critical resources — usually images and iframes — until they're about to enter the viewport. The native way to do it is the loading=\"lazy\" HTML attribute, which needs no JavaScript.” that one. Doing this well doesn’t magically boost your rankings, and it doesn’t guarantee a passing speed score either — it just makes your pages fast, and speed is what counts, so check your actual results before and after.
What image optimization actually does
Images are almost always the heaviest thing on a web page. Google’s own docs say images are “often the largest contributor to overall page size, which can make pages slow and expensive to load.” So optimizing them is really about one thing: cutting the bytes your visitor has to download, so your page shows up quickly.
Evidence for this claim Images are often a major contributor to page weight, and Google recommends responsive image and optimization techniques for a fast user experience. Scope: Google Search image guidance about performance; no claim that a particular format directly improves rankings. Confidence: high · Verified: Google Search Central: Google Images SEOThe part that surprises people: the format itself is not a ranking boost. Switching your JPEGs to WebP won’t lift your positions on its own. What it does is make the files smaller, which makes the page faster, and speed is what helps. This is the sister article to the broader Image SEOImage SEO is optimizing the images on your pages so search engines can discover, crawl, index, and rank them — in Google Images and visual search, and as part of standard web results. It spans file format, filenames, alt text, compression, responsive markup, structured data, and image sitemaps. hub — that one covers alt textAlt text is the value of the `alt` attribute on an HTML `<img>` element — a short text substitute chosen for the image's purpose and context, not a literal description of what it shows. It makes images accessible to screen-reader users and helps search engines understand images, mainly for image search., filenames, and image search; this one is the hands-on “make it load fast” guide.
The handful of things that matter
- Use a modern format. WebP and AVIF make files much smaller than old JPEGs and PNGs without looking worse. WebP is the safe default today.
- Compress it. Even a WebP can be too big. Run images through a compressor and find the point where the file is small but still looks fine.
- Don’t serve a giant image into a small space. If a picture only shows at 500 pixels wide, you don’t need a 3,000-pixel file — that’s wasted download.
- Lazy-load images down the page. Adding
loading="lazy"tells the browser to wait until you scroll near an image before loading it. Great for images below the fold. - Never lazy-load the big top image. The largest image people see when the page first loads is the one Google times your speed against. That one should load immediately.
The thing most people get wrong
They lazy-load everything — including the hero image at the top. It sounds smart (“load less stuff!”) but it’s backwards: the top image is the one your page-speed score is measured against, so delaying it makes your score worse. Load it eagerly, and tell the browser it’s important. I explain exactly how in the Advanced tab.
Evidence for this claim Lazy-loading an LCP image adds resource load delay; web.dev recommends loading it eagerly and considering high fetch priority. Scope: web.dev guidance for image-based LCP elements. Confidence: high · Verified: web.dev: Optimize LCPWant the precise version — the exact Google quotes, WebP-vs-AVIF trade-offs, the sizing
math, and the fetchpriority trick — switch to the Advanced tab.
TL;DR — Image optimization is a page-speed / Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. discipline, not a direct ranking lever. Format choice (WebP, AVIF) shrinks bytes but gives no SEO boost — Mueller has said so three separate ways; also weigh transparency, animation, and current browser support, not just compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. ratio. The single most valuable rule: never lazy-load your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image (usually the hero); that delays the very metric you’re optimizing. Give it
loading="eager"+fetchpriority="high", though priority hints only help a discovery/fetch-timing bottleneck, not every LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. problem. Nativeloading="lazy"is for images outside the initial viewport — not a fixed “below the fold” pixel line. CompressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. has no universal “right” quality — test per image type. Correct dimensions = rendered container size × device pixel ratio, and that container size itself shifts with responsive layout, so deliver asrcset/sizesrange (a wrongsizesvalue quietly downloads an oversized image) with a<picture>fallback. Images are the most common LCP element on the web, which is why this article cross-lists into Web Performance — but none of this guarantees a passing Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. score, a ranking change, or more traffic; measure before and after.
What image optimization optimizes for (set the myth up front)
Let me kill the biggest myth before anything else: image formatThe file encoding used to store an image (JPEG, PNG, WebP, AVIF, SVG, GIF) — it drives file size and Core Web Vitals, but carries no direct ranking weight. is a speed lever, not a ranking lever. Converting to WebP or AVIF does not earn you a ranking bump. It earns you smaller files, which earn you a faster page, which feeds Core Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. — and that’s the part search systems use. The chain is real but indirect, and collapsing it into “next-gen formats rank better” is where most competitor guides go wrong.
Google’s docs are blunt about why images matter for speed: they’re “often the largest contributor to overall page size, which can make pages slow and expensive to load,” and the advice is to “apply the latest image optimization and responsive image techniques to provide a high quality and fast user experience” (Google Search Central — Images). Note the framing: fast user experience, not a ranking reward for the file format.
Evidence for this claim Images are often a major contributor to page weight, and Google recommends responsive image and optimization techniques for a fast user experience. Scope: Google Search image guidance about performance; no claim that a particular format directly improves rankings. Confidence: high · Verified: Google Search Central: Google Images SEOFor the what/why of image SEOImage SEO is optimizing the images on your pages so search engines can discover, crawl, index, and rank them — in Google Images and visual search, and as part of standard web results. It spans file format, filenames, alt text, compression, responsive markup, structured data, and image sitemaps. overall — alt textAlt text is the value of the `alt` attribute on an HTML `<img>` element — a short text substitute chosen for the image's purpose and context, not a literal description of what it shows. It makes images accessible to screen-reader users and helps search engines understand images, mainly for image search., filenames, image sitemapsAn image sitemap is a sitemap (or an extension added to an existing sitemap) that lists the images on your pages using Google's image namespace, helping Google discover images it might otherwise miss., structured data, image-search ranking — that’s the parent Image SEOImage SEO is optimizing the images on your pages so search engines can discover, crawl, index, and rank them — in Google Images and visual search, and as part of standard web results. It spans file format, filenames, alt text, compression, responsive markup, structured data, and image sitemaps. hub’s job. This article is the canonical how: formats, compression, sizing, and loading strategy.
Lead with the rule everyone breaks: never lazy-load your LCP image
If you take one thing from this page, take this. The Largest Contentful Paint (LCP) element — the biggest thing painted in the viewport on load — is “either an image or a web font,” per web.dev (Optimize LCP), and on most pages it’s an image: the hero, the featured image, the product shot. web.dev puts the rule about as bluntly as Google ever phrases anything:
Evidence for this claim Lazy-loading an LCP image adds resource load delay; web.dev recommends loading it eagerly and considering high fetch priority. Scope: web.dev guidance for image-based LCP elements. Confidence: high · Verified: web.dev: Optimize LCP“Never lazy-load your LCP image, as that will always lead to unnecessary resource load delay, and will have a negative impact on LCP.”
This is the nuance most “just use lazy loadingLazy loading defers loading of off-screen or non-critical resources — usually images and iframes — until they're about to enter the viewport. The native way to do it is the loading=\"lazy\" HTML attribute, which needs no JavaScript.” advice misses entirely. Lazy-loading is great — for images below the fold. Apply it to the LCP image and you actively delay the one metric you’re trying to improve. web.dev’s lazy-loading guide says the same thing from the other direction: “Don’t lazy-load images that are likely to be in-viewport when the page loads, especially LCP images” (Browser-level lazy loading).
I’ve made the same argument in my own LCP article on Ahrefs:
the largest element “is usually going to be a featured image or maybe the <h1> tag,”
and the fixes follow from that. “If you don’t need the image, the most impactful solution
is to simply get rid of it. If you must have the image, I suggest optimizing the size and
quality to keep it as small as possible.” You should “lazy load any images that you don’t
need immediately” — but the flip side is a hard rule I put in caps for a reason: “Do not
lazy load images above the fold!”
fetchpriority="high" on the LCP image
Not lazy-loading the hero is necessary but not sufficient. To make sure the LCP image loads as early as possible, hint its priority to the browser. From web.dev:
“You can hint to the browser as to which resources are most important using the
fetchpriorityattribute… It’s a good idea to setfetchpriority=\"high\"on an<img>element if you think it’s likely to be your page’s LCP element.”
<img src="/hero.webp" alt="…" fetchpriority="high" width="1200" height="675">In my LCP write-up I describe fetchpriority="high" the same way — it “can be used on
<img> or <link> tags and tells browsers to get the image early” — and I pair it with
Early Hints (a 103 response) as a complementary way to start the fetch before the
main HTML even arrives. So the LCP recipe is: eager load + fetchpriority="high" (+ Early
Hints if your stack supports them). Everything else on the page can lazy-load.
Treat fetchpriority and preload as bottleneck-specific tools, not a guaranteed fix. They
help when the LCP image is discovered or fetched late; they do nothing for a slow server
response, a render-blocking resource ahead of the image, or a genuinely oversized file. Confirm
which bottleneck you actually have (PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. or LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. breaks LCP into its
subparts) before assuming a priority hint alone will move the number.
Native loading="lazy" — free, simple, and correct below the fold
For every image that isn’t in the initial viewport, native lazy loadingLazy loading defers loading of off-screen or non-critical resources — usually images and iframes — until they're about to enter the viewport. The native way to do it is the loading=\"lazy\" HTML attribute, which needs no JavaScript. is the easiest
win in performance. web.dev: “You can use the loading attribute to lazy-load images
without the need to write custom lazy-loading code or use a separate JavaScript library.”
<img src="/below-the-fold.webp" alt="…" loading="lazy" width="800" height="600">Two things keep this safe:
- Base it on the initial viewport, not a fixed “below the fold” line. “The fold” isn’t a
fixed pixel count — it shifts with viewport size and layout. The actual test is whether the
image is likely to be visible when the page first paints. Anything that is — and especially
the LCP image — gets
loading="eager"(the default), neverlazy. - Prefer the native attribute over JS hacks. JavaScript lazy-loaders that hide the real
URL in
data-srcand never expose asrcrisk not being indexed at all. Nativeloading="lazy"(or a clean IntersectionObserver) keeps thesrcvisible to crawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index.. The parent Image SEO hub covers that indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. caveat in full.
Modern formats: WebP vs. AVIF vs. JPEG/PNG
Formats are where the myth-busting matters most, so let’s be precise about what each buys you — which is bytes, not rankings.
- WebP — “often has better compression than JPEG, PNG, or GIF, offering both lossy and lossless compression” (web.dev — Image performance). Roughly 25–35% smaller than JPEG with near-universal browser support. The safe default for photos today.
- AVIF — “supports both lossy and lossless compression, and tests have shown greater than 50% savings when compared to JPEG in some cases.” Best-in-class compression, slightly less universal support, so pair it with a WebP or JPEG fallback.
- JPEG — the universal fallback for photographs.
- PNG — when you need transparency or crisp-edged graphics.
- SVG — logos and icons: vector, scales infinitely, tiny.
Which format to reach for also depends on what the image needs to do, not just which one compresses hardest: transparency, animation, and how consistently a browser or tool supports that specific combination all factor into the choice alongside the raw size savings above — check current support for the exact feature you need, especially for anything animated, before you commit to one format as the default.
Google Search supports “BMP, GIF, JPEG, PNG, WebP, SVG, and AVIF” referenced in an <img>
src. Serve the modern format with a graceful fallback using <picture>:
<picture>
<source srcset="/photo.avif" type="image/avif">
<source srcset="/photo.webp" type="image/webp">
<img src="/photo.jpg" alt="…" width="1200" height="800" loading="lazy">
</picture>The <img src> at the bottom is your safety net — older browsers and crawlers fall back to
it, and it’s the URL Google actually indexes.
Does format affect rankings? (No — and Mueller has said so three ways)
This is the single myth-busting thread worth pulling through the whole topic. Three separate, independently-timed John Mueller statements all land on the same conclusion — format affects crawl/index mechanics and page weight, never ranking directly:
- AVIF gives no SEO boost. After Google added native AVIF support, Mueller confirmed there’s no “SEO boost” for using AVIF over other supported formats (SE Roundtable coverage).
- WebP is “fine.” “WebP images are fine for Image Search” — “fine,” notably, not “better” (SE Roundtable coverage).
- WebP indexing quirks aren’t format-specific. When people saw WebP files show as “Crawled – currently not indexedA Google Search Console Page Indexing status meaning Googlebot fetched the page but Google decided not to index it — usually a content- or site-quality signal, not a technical error.” in GSC, Mueller’s point was that image files aren’t indexed as HTML pages, and he didn’t believe the phenomenon was limited to WebP at all (SEJ coverage).
Compression and quality: there’s no universal “right” setting
The most common bad advice in image guides is a single “compress to 80%” bullet. web.dev is explicit that no such magic number exists:
“When compressing, there isn’t a universal setting suitable for all cases. The recommended approach would be to experiment with different compression levels until you find a good compromise between image quality and file size.”
Practically: test per image type. Photographs tolerate aggressive lossy compression well; graphics, logos, and screenshots with text show artifactsClaude's feature for generating and publishing interactive mini-apps from chat. quickly and often want lossless or a higher quality setting. Instead of trusting one slider, export the same image at two or three quality levels and eyeball them at display size — the smallest one you can’t visually distinguish from the original is your answer. That’s a real workflow, not “run it through TinyPNG and hope.”
Correct dimensions: container size × device pixel ratio
“Just make it smaller” isn’t the rule — matching the rendered size × the device pixel ratio (DPR) is. From web.dev:
“An image displayed in a 500 pixel by 500 pixel container would be optimally sized at 500 pixels by 500 pixels.”
“If the device has a DPR of 2 and the image is displayed in a 500 pixel by 500 pixel container, then a square 1000 pixel image… is now the optimal size.”
So a 500×500 container on a 2× (Retina-class) display wants a 1,000×1,000 source. Go bigger
than that and you waste bytes with no perceptible gain; go smaller and it looks soft on
high-DPR screens. This is why you serve a range of sizes and let the browser pick, using
srcset + sizes:
<img
src="/photo-800.webp"
srcset="/photo-400.webp 400w, /photo-800.webp 800w, /photo-1600.webp 1600w"
sizes="(max-width: 600px) 100vw, 500px"
alt="…" width="800" height="600" loading="lazy">The browser reads the container width (sizes) and its own DPR, then picks the right
candidate from srcset — the responsive-delivery version of the DPR math above. Google
recommends <picture> or srcset for responsive images and says to “always specify a
fallback URL using the src attribute.”
Get sizes wrong and nothing warns you. If the value you declare doesn’t match how wide the
image actually renders — a common bug after a layout or CSS change — the browser has no way to
know that and simply picks a candidate based on the inaccurate number you gave it, which
typically means it downloads a larger file than the layout needs. That silently undoes the
format and compression work above. The only reliable way to catch it: open DevTools’ Network
panel, find the image request, and compare the delivered file’s dimensions against the
container’s actual rendered width.
That 500×500 example above is illustrative, not a site-wide number to hard-code — the same
hero image can render at a different width on mobile than on desktop, so “container size” moves
with your responsive layout rather than staying fixed. That’s exactly why you deliver a
srcset range instead of exporting one “optimal” size and calling it done.
After changing formats, loading hints, and responsive sources, audit the raw HTML for declared dimensions, loading attributes, supported formats, alt coverage, and ImageObject signals with my free Image SEO Checker Free
- Run the public URL after the optimized markup is deployed.
- Review the source-backed loading, dimension, format, alt, and ImageObject findings independently.
- Use a rendered performance test for transfer size, rendered dimensions, and the real LCP element—the checker marks those as not evaluated rather than guessing.
Why this all ties back to Core Web Vitals
The throughline connecting every technique above is LCP. Images are the most common LCP element on the web, and LCP is one of the three Core Web Vitals. Google’s target: “LCP should occur within 2.5 seconds” at the 75th percentile of page loads across mobile and desktop (web.dev — Vitals). Core Web Vitals “apply to all web pages, should be measured by all site owners, and will be surfaced across all Google tools.”
So image optimization isn’t a discrete ranking factor — it’s a contributor to a page-experience signal (Core Web Vitals) that ranking systems do use. That distinction is the accurate framing, and it’s why this article lives in both the Image SEO cluster and the Web Performance cluster. For the deep dive on the metric itself, see Core Web Vitals and LCP in Web Performance.
One more caution worth stating plainly: none of the fixes on this page guarantee anything. Image bytes are only one possible component of LCP — web.dev’s own breakdown of LCP subparts includes things like server response time and render-blocking resourcesRender-blocking resources are CSS and synchronous JavaScript files a browser must download and process before it can paint any visible content. They sit on the critical rendering path and delay First Contentful Paint and Largest Contentful Paint. ahead of the image, none of which format or compression touch — and image dimensions are only one input into CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good., not a guarantee of a particular score. Shrinking a hero image can measurably help, do nothing, or (if something else is the real bottleneck) barely move the number at all. Optimizing images also doesn’t itself guarantee a passing Core Web Vitals assessment, a ranking change, more traffic, more conversions, or an AI-search citation — those depend on far more than image bytes. Treat every image fix as a hypothesis, not a done deal: measure LCP and CLS before and after, in the lab and in the field, and let that data — not the assumption that optimizing “worked” — tell you whether it moved anything.
Common implementation pitfalls
- CSS background images aren’t indexed. Devs sometimes swap an
<img>for abackground-imagefor layout convenience. Google “can find images in thesrcattribute of<img>element (even when it’s a child of other elements, such as the<picture>element)” but “doesn’t index CSS images.” If you want the image in image search, keep it in an<img>. (This one’s performance-adjacent, but the mistake is common enough to flag.) - Don’t bulk-rename existing files for a performance/SEO “refresh.” Mueller has said it takes “a lot of time” for Google’s systems to reprocess renamed images and the effect is minimal if your context is already good — the parent Image SEO hub covers this in full.
- Missing width/height. Always set intrinsic
widthandheight(or CSSaspect-ratio) so the browser can reserve space before the image loads — this reduces image-driven layout shift, but it’s one input into CLS among several, not a guarantee of a particular score.
Quick recipe
- Hero / LCP image: modern format, right-sized,
loading="eager",fetchpriority="high". - Everything below the fold:
loading="lazy". - Serve WebP/AVIF with a
<picture>srcfallback. - Size to container × DPR; deliver a
srcsetrange withsizes. - Compress per image type — test 2–3 quality levels, don’t trust one slider.
- Always set
width/height.
For the rest of image SEO — alt textAlt text is the value of the `alt` attribute on an HTML `<img>` element — a short text substitute chosen for the image's purpose and context, not a literal description of what it shows. It makes images accessible to screen-reader users and helps search engines understand images, mainly for image search., filenames, image sitemapsAn image sitemap is a sitemap (or an extension added to an existing sitemap) that lists the images on your pages using Google's image namespace, helping Google discover images it might otherwise miss., structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding., and image-search ranking — head back to the Image SEO hub.
AI summary
A condensed take on the Advanced version:
- Image optimization = speed, not a ranking lever. Format choice (WebP/AVIF) shrinks bytes → faster page → better Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data.. There’s no direct ranking boost for the format itself — Mueller confirmed this three separate ways (AVIF “no SEO boost,” WebP “fine,” WebP indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. quirks aren’t format-specific).
- The #1 rule: never lazy-load your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image. The image likely to be visible when the
page first paints (usually the hero) times your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good.; lazy-loading it delays the exact
metric you’re fixing. Give it
loading="eager"+fetchpriority="high"(optionally Early Hints) — though priority hints only fix a discovery/fetch-timing bottleneck, not every LCP problem (check LCP’s subparts before assuming a hint alone will help). - Native
loading="lazy"is free and correct — for images outside the initial viewport, not a fixed “below the fold” pixel line. Avoid JS lazy-loaders that hide the URL indata-src. - Formats: WebP is the safe default (~25–35% smaller than JPEG); AVIF compresses further
(50%+ in some tests) with a fallback. Choice also depends on transparency, animation, and
current browser/tool support, not just compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. ratio. Serve via
<picture>with an<img src>fallback that Google indexes. - CompressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits.: no universal “right” quality — test per image type (photos compress hard; text/graphics artifact fast).
- Sizing: correct size = rendered container size × device pixel ratio (500px container
at 2× DPR = 1,000px source) — and that container size itself shifts with responsive layout,
so deliver a range via
srcset+sizesrather than one fixed export. A wrongsizesvalue silently makes the browser download an oversized candidate. - Why it matters: images are the most common LCP element; LCP target is 2.5s at the 75th percentile. That’s why this cross-lists into Web Performance — but LCP has other subparts (server response timeTime to First Byte — the time from the start of a request to when the first byte of the response arrives. It's a diagnostic metric (not a Core Web Vital) and a major input to FCP and LCP; ≤0.8 s is good., render-blocking resourcesRender-blocking resources are CSS and synchronous JavaScript files a browser must download and process before it can paint any visible content. They sit on the critical rendering path and delay First Contentful Paint and Largest Contentful Paint.) that image bytes alone don’t fix.
- No guarantees: optimizing images doesn’t itself guarantee a passing Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. score, a ranking change, more traffic, more conversions, or an AI-search citation. Measure LCP/CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. before and after, in the lab and the field.
- Pitfalls: CSS
background-imageisn’t indexed; don’t bulk-rename files; always setwidth/height— it can reduce layout shift but doesn’t guarantee a particular CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. score.
Official documentation
Primary-source documentation from the search engines and the Chrome team.
Google / web.dev
- Image performance (web.dev “Learn Performance”) — formats, the “no universal compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. setting” point, and the DPR sizing math.
- Browser-level image lazy loading (web.dev) — how native
loading="lazy"works and the “don’t lazy-load in-viewport / LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. images” exception. - Optimize LCP (web.dev) —
fetchpriority, the LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. resource is an image or font, and “never lazy-load your LCP image.” - Fetch Priority API (web.dev) — the full
fetchpriority="high"explainer for LCP images. - Web Vitals (web.dev) — Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. definitions and the LCP ≤ 2.5s / 75th-percentile threshold.
- Google Images best practices — supported formats,
<img>/<picture>indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. (not CSS backgrounds), responsive images, and the fallback-srcrecommendation.
Bing / Microsoft
- Bing does not publish an image-optimization-specific technical guide as detailed as Google’s; the relevant guidance lives inside the general Bing Webmaster Guidelines, which treat page speed (including image weight) as a consideration. I’m flagging this honestly rather than manufacturing a Bing “quote” that doesn’t exist.
- Bing Visual Search — object-level visual searchMultimodal search lets you query and get results across more than one modality — text, images, video, and audio together. Instead of typing words, you can point your camera, circle something on screen, or combine an image with a question, and the system understands them jointly.; relevant to image discovery, separate from the page-speed effects of format/compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits..
Quotes from the source
On-the-record statements from Google’s Chrome team and Search Advocates. Where a page exposes the text, the link is a deep link that jumps to the quoted passage.
web.dev (Google Chrome team) — the LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. rules
- “Never lazy-load your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image, as that will always lead to unnecessary resource load delay, and will have a negative impact on LCP.” Jump to quote
- “Don’t lazy-load images that are likely to be in-viewport when the page loads, especially LCP images.” Jump to quote
- “It’s a good idea to set
fetchpriority=\"high\"on an<img>element if you think it’s likely to be your page’s LCP element.” — web.dev, Optimize LCP.
web.dev (Google Chrome team) — formats, compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits., sizing
- “WebP often has better compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. than JPEG, PNG, or GIF, offering both lossy and lossless compression.” Jump to quote
- “AVIF supports both lossy and lossless compression, and tests have shown greater than 50% savings when compared to JPEG in some cases.” — web.dev, Image performance.
- “When compressing, there isn’t a universal setting suitable for all cases. The recommended approach would be to experiment with different compression levels until you find a good compromise between image quality and file size.” — web.dev, Image performance.
- “An image displayed in a 500 pixel by 500 pixel container would be optimally sized at 500 pixels by 500 pixels.” … “If the device has a DPR of 2 … then a square 1000 pixel image … is now the optimal size.” — web.dev, Image performance.
Google Search Central — why images matter for speed
- “images are often the largest contributor to overall page size, which can make pages slow and expensive to load.” Jump to quote
web.dev — Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data.
- “Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. are the subset of Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. that apply to all web pages, should be measured by all site owners, and will be surfaced across all Google tools.” Jump to quote
John Mueller, Google — format is not a ranking lever
- On AVIF: there is no “SEO boost” for using AVIF files. Coverage
- On WebP: “WebP images are fine for Image Search.” Coverage
Image optimization checklist
Run this pass on any performance-sensitive page:
- Identified the LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image (usually the hero / featured image / first product shot).
- LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image is not lazy-loaded — it uses
loading="eager"(the default). - LCP image has
fetchpriority="high"(consider Early Hints if your stack supports it). - Every image below the fold has
loading="lazy". - Modern format served (WebP default, AVIF where supported) with a
<picture>srcfallback. - Each image is sized to its container × device pixel ratio — no 3,000px files in 500px slots.
- Responsive delivery via
srcset+sizeswhere images render at different widths. - CompressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. tested per image type (2–3 quality levels compared at display size), not one blanket setting.
- Intrinsic
widthandheight(or CSSaspect-ratio) set on every image to reduce layout shiftCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. (CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.) — not a guarantee of a specific score. - No content image lives only in a CSS
background-image(those aren’t indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed.). - Lazy loadingLazy loading defers loading of off-screen or non-critical resources — usually images and iframes — until they're about to enter the viewport. The native way to do it is the loading=\"lazy\" HTML attribute, which needs no JavaScript. uses the native attribute (or clean IntersectionObserver), not a JS hack that hides the URL in
data-src. - Verified LCP in the field (CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. / PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking.), aiming for ≤ 2.5s at the 75th percentile.
Image optimization cheat sheet
The levers — what each does and the best practice
| Lever | What it does | Best practice |
|---|---|---|
| Format | Shrinks file size → faster page; no direct ranking boost | WebP default, AVIF where supported, <picture> with src fallback |
| CompressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. | Trades quality for bytes | No universal setting — test 2–3 quality levels per image type |
| Dimensions | Wrong size wastes bytes or looks soft | Container size × DPR (500px @ 2× = 1,000px source) |
| Responsive delivery | Right-sized image per device | srcset + sizes; browser picks by width & DPR |
loading="lazy" | Defers off-screen images | Below the fold only — never the LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image |
| LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image | Times your Largest Contentful Paint | loading="eager" + fetchpriority="high"; never lazy-load |
width/height | Reserves layout space | Always set intrinsic dimensions — reduces CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good., doesn’t guarantee a score |
<img> vs CSS bg | Only <img> gets indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. | Keep content images in <img>, not background-image |
Fast facts
- Format is a speed lever, not a ranking lever — Mueller: no AVIF “SEO boost”; WebP “fine.”
- WebP ≈ 25–35% smaller than JPEG; AVIF often 50%+ smaller in tests.
- The single highest-value rule: never lazy-load your LCP image.
- LCP target: ≤ 2.5s at the 75th percentile (mobile + desktop).
- Supported formats: BMP, GIF, JPEG, PNG, WebP, SVG, AVIF.
- Correct size = rendered container size × device pixel ratio.
The mistake that costs you your LCP score
Lazy-loading the hero image is the single most expensive mistake covered in this article, and it’s the one worth calling out on its own before the rest.
- Wrong: applying
loading="lazy"(or a JS lazy-loader) to the largest above-the-fold image — usually the hero, featured image, or first product shot. Why it’s wrong: that image is almost always your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. element, and web.dev is explicit that lazy-loading it “will always lead to unnecessary resource load delay, and will have a negative impact on LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good..” You end up delaying the exact metric you were trying to improve. Do instead: give the LCP imageloading="eager"(the default) plusfetchpriority="high", and reserveloading="lazy"for everything below the fold.
Trusting one blanket compression setting
- Wrong: running every image through the same “compress to 80%” preset regardless of content. Why it’s wrong: web.dev says plainly that “there isn’t a universal setting suitable for all cases” — a preset tuned for photographs will over- compress logos, screenshots, and text-heavy graphics into visible artifactsClaude's feature for generating and publishing interactive mini-apps from chat.. Do instead: export the same image at two or three quality levels and compare them at actual display size; pick the smallest one you can’t tell apart from the original, per image type.
Sizing images off the file you have, not the container
- Wrong: serving whatever resolution the original file happens to be (or a
single fixed size for every layout), instead of matching the image to where
it actually renders.
Why it’s wrong: per web.dev’s own math, correct size is the rendered
container size × the device’s pixel ratio — a 500×500 container at 2× DPR
needs a 1,000×1,000 source, not 500×500 and not 3,000×3,000. Go bigger and
you waste bytes with no visible gain; go smaller and it looks soft on
high-DPR screens.
Do instead: deliver a
srcsetrange withsizesso the browser can pick the right candidate for the container and the device.
Hiding real content images behind CSS
- Wrong: swapping an
<img>for abackground-imagefor layout convenience. Why it’s wrong: Google “doesn’t indexStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. CSS images” — a content image that only exists as abackground-imageis invisible to image search even if it’s fully optimized otherwise. Do instead: keep content images in an<img>(or as the<img>fallback inside a<picture>), and reserve CSS backgrounds for purely decorative treatments.
Skipping width/height to “save markup”
- Wrong: leaving intrinsic
widthandheight(or a CSSaspect-ratio) off<img>tags. Why it’s wrong: the browser can’t reserve layout space before the image loads, so the page jumps as each image arrives — hurting CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good., the Core Web Vital that sits alongside LCP. Do instead: always setwidth/height(oraspect-ratio) on every image, even ones you’re also optimizing for format and size.
The mental models
1. Never lazy-load your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. image.
The single highest-value rule in the whole topic. The largest above-the-fold
element — usually an image — is what your LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. is timed against. Lazy-loading
it doesn’t save anything; it just delays the metric you’re optimizing. Everything
else on the page is a candidate for loading="lazy"; the LCP image never is.
2. There’s no universal compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. setting. Treat “what quality should I compress to?” as a per-image question, not a site-wide policy. Photographs tolerate aggressive lossy compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits.; text-heavy graphics and screenshots don’t. The workflow is comparative — export at two or three quality levels and eyeball them at display size — not a single slider you set once and forget.
3. Correct size = container size × device pixel ratio.
“Smaller is better” isn’t the rule; matching is. The optimal source
dimensions are the size the image actually renders at, multiplied by the
device’s pixel ratio — a 500×500 container at 2× DPR wants a 1,000×1,000
source. This is the single formula that should decide every image’s export
size, and it’s why you deliver a range via srcset rather than one fixed
file.
4. Format is a speed lever, not a ranking lever. Collapse this chain correctly: format choice → smaller files → faster page → better Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. → a signal ranking systems do use. Skipping straight to “next-gen formats rank better” is the most common way competitor guides get this topic wrong — Mueller has said there’s no direct SEO boost for the format itself, three separate times.
The standing KPIs for image-driven page speed
These are the ongoing numbers that tell you whether your image-optimization work is actually landing — separate from any single image you resize or convert this week.
| Metric | What it tells you | How to pull it | Benchmark / realistic range | Cadence |
|---|---|---|---|---|
| LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. at the 75th percentile (field dataPerformance metrics captured from real users, not lab tests.) | Whether real visitors’ Largest Contentful Paint — usually an image — is fast enough, across the mix of devices and connections they actually use | CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. (via PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. or the Chrome UX Report API/BigQuery dataset) | web.dev’s published thresholds: ≤ 2.5s is “good,” up to 4s is “needs improvement,” above that is “poor” — measured at the 75th percentile per web.dev’s Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. guidance | 28-day rolling (CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program.’s window) |
| Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. pass/fail rate (LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. dimension) | The share of your page’s traffic meeting the “good” LCP threshold, tracked over time as you ship image fixes | Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results.’s Core Web Vitals reportThe Google Search Console report (under Experience) that shows how your indexed URLs perform on the Core Web Vitals — LCP, INP, and CLS — using real-user field data from CrUX, grouped by device, status, and clusters of similar-performing URLs., or CrUX history for the same URL/origin | No universal target beyond “trending toward 100% passing” — establish your own baseline before and after a round of image fixes, then watch the trend | Quarterly, plus immediately after any LCP-focused image change |
| Lab LCP on the specific page you changed | A fast, pre-deploy check of whether an individual image fix (eager-loading the hero, resizing, format swap) actually helped, before waiting for field data to catch up | PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. or LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. run against that URL | Lab scores run faster than real-world field data and won’t always match CrUX exactly — use lab results to catch regressions immediately, but trust the field (CrUX) number as the one that reflects real users | Before/after each image change; not a substitute for the field metric above |
Test yourself: Image Optimization
Five quick questions on formats, compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits., sizing, and loading strategy. Pick an answer for each, then check.
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Revision history
Compare the published article with an archived editorial snapshot. Added and removed words are shown only after you open a comparison.
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Added explicit no-guarantee framing for Core Web Vitals/ranking/traffic outcomes, refined the lazy-loading criterion from a fixed 'below the fold' line to the initial viewport, and explained the inaccurate-sizes oversized-download failure mode.
Change details
-
Image optimization does not itself guarantee a passing Core Web Vitals score, a ranking change, more traffic, more conversions, or an AI-search citation — measure LCP/CLS before and after in the lab and field.
-
A wrong srcset `sizes` value causes the browser to silently download an oversized image candidate; check DevTools' Network panel to catch it.
-
Lazy-loading decisions should be based on whether an image is likely visible in the initial viewport, not a fixed 'below the fold' pixel line; fetchpriority/preload are bottleneck-specific tools, not guaranteed LCP fixes.