The "Properly size images" audit (also called "uses responsive images") flags any image being served at a much higher resolution than its rendered display size — for example, a 1,920×1,080 JPEG displayed in a 480-pixel-wide column. The audit fires when serving a correctly sized variant would save more than ~10 KB per image.
srcset with width descriptors + a correct sizes attribute, generating variants at 320, 480, 640, 800, 1200, 1600, 2000.Think of it like shipping furniture in a moving truck. If a customer ordered a chair, sending it in a 40-foot semi means burning fuel to move 39 feet of empty air. Browsers do the same thing every time you serve a 2,000-pixel hero into a 500-pixel phone slot — except the "fuel" is your visitor's data plan and time-to-LCP.
Unlike many performance trade-offs, fixing oversized images has no downside. The image looks identical at the rendered size — it just arrives faster.
The audit doesn't just compare source dimensions to display dimensions in pixels — it converts that ratio into wasted bytes. The math matters because it's the source of the audit's most counterintuitive number: a 2× oversize is a 4× byte penalty.
Source image: 2000 × 1000 px → 2,000,000 px²
Display slot: 500 × 250 px → 125,000 px²
Pixel ratio (linear) = 2000 / 500 = 4×
Area ratio (quadratic) = 2,000,000 / 125,000 = 16×
If the source weighs 800 KB:
Right-sized variant ≈ 800 KB / 16 = 50 KB
Wasted bytes ≈ 800 KB - 50 = 750 KB
Audit fires (savings > ~10 KB) → "Properly size images"Notice the leverage: a hero that's only twice as wide as it needs to be is shipping four times as many bytes. Three times too wide is nine times the bytes. This is why oversized images are the easiest large performance win on most sites.
The audit fires on any single image where the right-sized variant would save more than approximately 10 KB. Tiny thumbnails that are 100 KB instead of 95 KB are ignored — the audit targets meaningful waste, not perfectionism. In practice, the offenders are almost always hero images, full-width product photography, and CMS-uploaded inline images.
The audit measures the rendered size in device pixels, accounting for device pixel ratio (DPR). On a phone with DPR 3 displaying an image at 375 CSS pixels wide, the "right size" is 375 × 3 = 1,125 device pixels — not 375. Audits respect DPR; your build pipeline must too.
The audit gives you the list. The trick is grouping fixes by template (one bad product page is usually one bad product template).
srcset + sizes patch or a one-click GitHub PR.clientWidth. If intrinsic is >2× rendered × DPR, it's an offender.For any image that scales with the layout, use width-descriptor srcset plus a sizes attribute that mirrors your CSS breakpoints. The browser will pick the smallest variant that satisfies the device-pixel requirement.
<img
src="hero-800.jpg"
srcset="hero-320.jpg 320w,
hero-480.jpg 480w,
hero-800.jpg 800w,
hero-1200.jpg 1200w,
hero-1600.jpg 1600w,
hero-2000.jpg 2000w"
sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw"
alt="Product hero"
width="2000" height="1125">Cover the common viewport × DPR combinations. A solid default: 320, 480, 640, 800, 1200, 1600, 2000. Anything narrower won't cover modern phones at DPR 3 (375 × 3 = 1125 — you need a 1200w variant). Anything wider is overkill for the median display.
sizes must reflect what your CSS actually does. The most common bug: a sidebar image at 33% of viewport but no sizes attribute, so the browser defaults to 100vw and downloads triple the bytes it needs.
<!-- Wrong: sizes missing → browser assumes 100vw -->
<img srcset="..." src="...">
<!-- Right: sizes mirrors the CSS layout -->
<img srcset="..." sizes="(max-width: 600px) 100vw, 33vw" src="...">The audit only checks dimensions, but you should fix format at the same time. A 2,000×1,125 hero served as a JPEG at quality 80 is ~800 KB; the same image served as a right-sized AVIF is often ~80 KB — a 10× win.
<picture>
<source type="image/avif"
srcset="hero-800.avif 800w, hero-1600.avif 1600w"
sizes="(max-width: 600px) 100vw, 50vw">
<source type="image/webp"
srcset="hero-800.webp 800w, hero-1600.webp 1600w"
sizes="(max-width: 600px) 100vw, 50vw">
<img src="hero-800.jpg"
srcset="hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Hero" width="1600" height="900">
</picture>For UI assets that always render at the same CSS size (avatars, icons, logos), use 1x/2x descriptors instead of width descriptors. Simpler markup, same audit result.
<img src="avatar.png"
srcset="avatar.png 1x, avatar@2x.png 2x"
width="64" height="64" alt="">Always include width and height attributes. They don't affect srcset selection — they let the browser reserve the right slot before the image arrives, preventing layout shift. Fixing image size is wasted work if you regress CLS in the process.
The hero image should be eager and use fetchpriority="high" so the browser starts the request immediately. Every below-the-fold image gets loading="lazy"so it doesn't compete with critical resources.
Don't hand-export. Use sharp in a build step, framework image components (Next.js <Image>, Nuxt <NuxtImg>, Astro <Image>), or an image-optimization service that resizes from URL parameters. These produce the right widths and modern formats without per-image manual work.
Editors uploading 4,000-pixel camera originals into a 600-pixel content column is the single most common source of audit failures on content sites. Either resize on upload, or pipe every uploaded image through a build-time / on-the-fly resizer.
What's happening: The page has <img src="hero-2000.jpg"> with no srcset. Every device — including 375-pixel phones — downloads the 2,000-pixel master.
Fix: Generate variants at 320/480/800/1200/1600/2000 and add srcset with width descriptors plus a sizes attribute that matches the CSS rendered width.
What's happening: srcset is wired up correctly, but sizes is omitted or set to 100vw on an image that actually fills only a 33% column. The browser over-fetches because it has the wrong layout information.
Fix: Set sizes to reflect the real rendered width at each breakpoint — for example, sizes="(max-width: 600px) 100vw, 33vw".
What's happening: Editors paste 4,000-pixel-wide JPEGs into a column that's 600 pixels wide. The CMS doesn't generate variants, so the original ships to every visitor.
Fix: Either configure the CMS to generate responsive variants on upload, or front the media library with an image-optimization service / build-time resizer that emits a srcset.
What's happening: The srcset tops out at 800w, but a 375-pixel phone at DPR 3 needs 1,125 device pixels — so the browser still picks 800w and the image looks soft. Worse, on the LCP image, the audit may still flag the bytes as wasted because the rendered size is being measured at higher DPR.
Fix: Always include variants up to roughly 2× your largest desktop layout slot — typically 1200w, 1600w, 2000w — so DPR-3 mobile and high-DPI desktop both have a sharp variant.
The audit's "wasted bytes" calculation scales with the square of the linear oversize ratio. Use this table to see why even small mismatches matter.
| Source vs. Display (linear) | Byte Multiplier (area) | Source 800 KB → Right-Sized | Audit Status |
|---|---|---|---|
| 1× (perfectly sized) | 1× | ~800 KB | Pass |
| 1.5× (slightly oversized) | 2.25× | ~355 KB right-sized → 445 KB wasted | Fail |
| 2× (commonly seen) | 4× | ~200 KB right-sized → 600 KB wasted | Fail |
| 3× (CMS upload typical) | 9× | ~89 KB right-sized → 711 KB wasted | Fail |
| 4× (camera original on phone) | 16× | ~50 KB right-sized → 750 KB wasted | Fail |
It means every image on the page is being delivered at a resolution close to its rendered display size (in device pixels), so the browser isn't downloading and decoding pixels that will be thrown away. Audits flag any image where serving a correctly sized variant would save more than approximately 10 KB.
Approximately 10 KB of savings per image. The audit ignores trivial mismatches and focuses on images where right-sizing yields a meaningful payload reduction. On pages with multiple oversized images, total savings frequently reach 200–500 KB or more.
Because image bytes scale with area, not linear dimension. Doubling both the width and the height quadruples the pixel count, and roughly quadruples the bytes at constant compression quality. Three times too wide is nine times the bytes; four times too wide is sixteen times the bytes.
Yes. A modern phone displaying an image at 375 CSS pixels wide on a DPR-3 screen needs 1,125 device pixels to look sharp. A srcset that tops out at 800w will still over-soften the image (and may still trip the audit). Always include variants up to roughly 2× your largest desktop layout slot.
No. CSS sizing tells the browser how to display the image, not which file to download. With CSS-only resizing, the browser still downloads the full-resolution source — it just paints it smaller. The audit is exactly designed to catch that case. The fix is at the network layer (srcset + sizes), not the rendering layer.
Indirectly but meaningfully. AI-driven search systems preferentially cite pages that already rank well in classic search, and Core Web Vitals — especially LCP — are part of that ranking. Oversized hero images are the most common cause of failing LCP on mobile (Web Almanac 2025). Fix the audit, improve LCP, improve rankings, improve odds of being cited by an AI Overview.
Mostly yes. Next.js <Image>, Nuxt <NuxtImg>, Astro <Image>, and SvelteKit's enhanced:img all generate variants and emit srcset automatically. The remaining failure mode is a wrong or missing sizes prop — which makes the browser over-fetch even though the variants exist. Always pass a sizes value that matches the actual rendered width.
The "Properly size images" audit is one of the easiest large performance wins on the modern web. Because image bytes scale with area, even modest right-sizing — going from a 2× oversize to a perfect fit — cuts a hero image's bytes by 75%. Pages with multiple oversized images often shed 200–500 KB on a single fix, and the LCP improvement on mobile is usually visible within a single Core Web Vitals report cycle.
The fix is mechanical: generate variants at 320/480/800/1200/1600/2000, wire up srcset with width descriptors, and write a sizes attribute that mirrors your CSS. Run a Greadme deep scan to surface every offender on every page, with the rendered dimensions and source dimensions side by side — so you fix the worst ones first.