/ โ† Image Optimisation Fixes / Image Dimensions
In this guide
  1. What the dimensions finding actually means
  2. The fix, step by step
  3. Markup that gets it right
  4. Getting sizes right: common mistakes
  5. Platform notes
  6. Edge cases
  7. Keeping dimensions in check
  8. Questions and answers

What the dimensions finding actually means

Every raster image is a grid of pixels. A photo exported at 4000 x 3000 holds twelve million of them. When the browser shows that photo in a card 400 CSS pixels wide, it has to decode all twelve million into memory and then scale them down. Most of the download is thrown away.

The audit compares two numbers for each image:

Screens with a high device pixel ratio (DPR) need more than one image pixel per CSS pixel to look sharp. A phone with a DPR of 3 fills a 400 CSS pixel slot with 1200 physical pixels. So "correctly sized" means roughly the rendered width multiplied by the screen's DPR, not the rendered width alone. The waste starts when the file is much larger than that product.

๐Ÿ’ก In Chrome developer tools, hover over an img in the Elements panel and a tooltip shows both the rendered size and the intrinsic size side by side, for example "360 x 240 pixels (intrinsic: 2400 x 1600 pixels)". That single tooltip tells you whether the image is a problem.

Why it costs more than bandwidth

Oversized dimensions affect more than transfer size. Decoding a huge image takes processor time and memory, which on a mid-range phone can delay rendering and make scrolling stutter. The file size and the pixel count are linked but not the same: a large, very compressed JPEG can be small in kilobytes and still costly to decode. That is why this finding sits alongside the file size finding rather than replacing it.

Compression settings, quality levels and format conversion are covered in the oversized files guide and the image format guide. Reserving space with width and height attributes to stop jumping is covered in the layout shift guide. This page is about pixel counts and choosing between variants.

The fix, step by step

Step 1

Measure rendered size against intrinsic size

Run the Image Optimisation audit and list the images it reports as oversized. For each, open the page in developer tools and hover the element to read its rendered and intrinsic sizes, or run a short console snippet that prints currentSrc, naturalWidth and the element's clientWidth for every image. Divide the intrinsic width by the rendered width. Anything above about three on a desktop view, or above four on a phone view, is sending pixels no screen can use.

Step 2

Map each image slot across breakpoints

An image does not have one rendered size; it has one per layout. Using device emulation, record how wide each image slot is at a small phone width, a large phone, a tablet and a desktop. A product grid might show images at 100 per cent of the viewport minus padding on phones, half the viewport on tablets and a fixed 280 pixels on desktop. Write these rules down, because they become your sizes attribute later.

Step 3

Choose a small set of target widths

Take the smallest and largest widths from your slot map, multiply the largest by two for high-density screens, and fill in a few steps between. Four to six widths per image is plenty for most sites, for example 320, 640, 960, 1280 and 1920. Capping at around twice the largest display width is a sensible limit, because beyond that most people cannot see the extra detail while the bytes keep climbing. Use the same set site-wide so caches work well.

Step 4

Generate the width variants

Create each width from the original high-resolution master, never by enlarging a small file. On a static or custom site, run a build step with Sharp or ImageMagick that writes files named with their width, such as workshop-960.webp. WordPress and Shopify generate variants automatically, and an image CDN can resize on request from a URL parameter. Whichever route you take, keep aspect ratios identical across the variants so the browser can swap between them freely.

Step 5

Write srcset with width descriptors

List every variant in the srcset attribute with a w descriptor that states the file's true pixel width, such as workshop-640.webp 640w. The descriptor must match the file exactly, because the browser trusts it when doing its sums. Keep a sensible middle size in src as a fallback. Use x descriptors such as 1x and 2x only for images with a fixed display size, like a logo that is always 160 pixels wide.

Step 6

Write a sizes value that matches the layout

Turn the slot map from step two into a sizes list of media conditions and widths, most specific first, ending with a default that has no condition. For the product grid above that could be (min-width: 1200px) 280px, (min-width: 768px) 50vw, 100vw. Without sizes, the browser assumes the image fills the whole viewport and usually picks a file far larger than needed, which quietly undoes most of the benefit of srcset.

Step 7

Use picture only where the crop must change

If a wide banner shrinks to an unreadable strip on phones, you need a different crop, not just a smaller file. That is art direction, and it is the job of the picture element with source children using media conditions, each with its own srcset. Do not reach for picture just to change resolution; a plain img with srcset and sizes lets the browser choose and is simpler to maintain.

Step 8

Verify which file each device downloads

Reload each template in device emulation at two or three widths with the cache disabled, and check the Network panel or currentSrc to see which variant was chosen. The chosen width should be close to the slot width multiplied by the emulated device pixel ratio. If desktop still receives the largest file for a small slot, the sizes value is wrong. Then run the Image Optimisation audit again on the same pages.

Markup that gets it right

A content image in a flexible column

This photo from a fictional joinery site, Oakline Joinery, fills the column on phones, half the page on tablets and a fixed 720 pixel column on wide screens.

<img
  src="/img/workshop-960.webp"
  srcset="/img/workshop-480.webp 480w,
          /img/workshop-720.webp 720w,
          /img/workshop-960.webp 960w,
          /img/workshop-1440.webp 1440w"
  sizes="(min-width: 1100px) 720px,
         (min-width: 700px) 50vw,
         calc(100vw - 2rem)"
  width="1440" height="960"
  alt="Two joiners fitting an oak staircase handrail">

A phone 390 CSS pixels wide with a DPR of 3 works out that it needs about (390 minus 32) x 3, roughly 1074 pixels, and picks the 1440 file. The same phone at DPR 2 needs about 716 and takes the 720 file. A desktop showing the 720 pixel column on a standard screen takes the 720 file, and on a DPR 2 screen the 1440 file. Nothing larger than 1440 is ever sent.

A fixed-size image

<img src="/img/logo-160.png"
     srcset="/img/logo-160.png 1x, /img/logo-320.png 2x"
     width="160" height="48" alt="Oakline Joinery home">

Art direction with picture

<picture>
  <source media="(max-width: 699px)"
          srcset="/img/banner-square-600.webp 600w,
                  /img/banner-square-1000.webp 1000w"
          sizes="100vw">
  <img src="/img/banner-wide-1600.webp"
       srcset="/img/banner-wide-1000.webp 1000w,
               /img/banner-wide-1600.webp 1600w,
               /img/banner-wide-2400.webp 2400w"
       sizes="100vw"
       width="2400" height="900" alt="">
</picture>

Here the phone gets a square crop and larger screens get the wide one. The img inside still does the displaying; the source elements only change which set of files it chooses from. When the crops have different shapes, add width and height to each source so each crop reserves the right space.

Getting sizes right: common mistakes

The sizes attribute is where most responsive image setups go wrong, because it has to describe the CSS layout in a form the browser can use before any CSS has loaded.

MistakeWhat happensFix
No sizes at allBrowser assumes 100vw and fetches a file sized for the full screen width.Add a sizes value describing the real slot.
Conditions in the wrong orderThe first matching condition wins, so a broad rule listed first hides the narrower ones.Put the most specific or largest breakpoints first.
Percentages instead of vwPercentages are not allowed in sizes and the value is ignored.Use vw, px, em or calc().
Copying one sizes to every templateThumbnails in a sidebar are told they are full width.Write sizes per slot, in the component that outputs the image.
w descriptors that do not match the fileBrowser picks the wrong file or a blurry one.Generate descriptors from the real file width.

A value that is slightly too large wastes a few kilobytes; one that is badly too small makes images look soft on good screens. When unsure, err slightly large.

Browsers also have some freedom. Once a large variant is in the cache, a browser may reuse it rather than fetch a smaller one, and some browsers pick smaller files on slow connections or in data-saver modes. So small differences between what you calculate and what you see in testing are normal.

sizes="auto" for lazy-loaded images

Newer versions of Chromium-based browsers support sizes="auto" on images that also have loading="lazy". Because a lazy image is only fetched after layout, the browser can measure the real slot and choose accordingly. Write it as sizes="auto, (min-width: 700px) 50vw, 100vw" so browsers without support use the explicit list. It cannot work on eagerly loaded images, including your main image at the top of the page.

Platform notes

WordPress

WordPress creates several copies of each upload and outputs srcset and sizes for images inserted through the editor or wp_get_attachment_image(). Problems usually come from themes that hard-code the full-size URL, from page builders that bypass the core functions, or from a sizes value that assumes a wider column than the theme uses. The WordPress images guide goes into registering sizes and regenerating thumbnails.

Shopify

Shopify's CDN resizes images on request. In Liquid, the image_url filter takes a width parameter, and the image_tag filter can output a srcset for you through its widths parameter, with a sizes value you supply. Check older themes that request one very large width for every product card.

Next.js and other frameworks

The Next.js Image component builds srcset from configured device and image sizes, but only chooses well if you pass the sizes prop for images that are not full width. Our Next.js images guide covers the configuration.

Static and custom sites

A small Node script using Sharp can read each master image, write a fixed list of widths and formats, and output the srcset string for your templates. Keep the originals out of the public folder so they are never linked by mistake.

// resize.mjs: node resize.mjs originals/*.jpg
import sharp from "sharp";
import path from "node:path";
const widths = [480, 720, 960, 1440];
for (const file of process.argv.slice(2)) {
  const name = path.parse(file).name;
  for (const w of widths) {
    await sharp(file)
      .resize({ width: w, withoutEnlargement: true })
      .webp({ quality: 75 })
      .toFile(`public/img/${name}-${w}.webp`);
  }
}

The withoutEnlargement option stops Sharp from upscaling an original that is smaller than a target width; in that case, drop that width from the srcset for that image.

Edge cases

Keeping dimensions in check

Questions and answers

1. What does "properly size images" mean?

It means the file you send should have roughly as many pixels as the space it fills on screen, allowing for high-density displays, and no more. If an image is shown 400 pixels wide on a screen with a device pixel ratio of two, a file around 800 pixels wide is right. A 4,000 pixel file in the same slot wastes bandwidth, memory and decoding time. Performance tools flag the difference as potential savings when a smaller variant would do.

2. How large should my images be for high-resolution screens?

A good working rule is about twice the largest width the image is displayed at. That covers most laptops and phones with high-density screens. Phones with a device pixel ratio of three can use a little more, but the visible gain over twice the width is small while the file size grows quickly. Generate a few widths up to that cap, list them in srcset and let each device choose, rather than serving the largest file to everyone.

3. Why does the browser download the largest image in my srcset?

Usually because sizes is missing or wrong. Without sizes, the browser assumes the image fills the whole viewport, so on a wide desktop screen it picks a large file even for a small card. Other causes are w descriptors that do not match the files, a larger variant already sitting in the cache, or testing with a high device pixel ratio in emulation. Check currentSrc in the console to see exactly which file was chosen.

4. Should I use x descriptors or w descriptors in srcset?

Use x descriptors such as 1x and 2x when an image is always displayed at the same size, such as a logo or an avatar of fixed width. Use w descriptors with a sizes attribute when the display size changes with the layout, which is most content images. With w descriptors the browser can combine the slot width and screen density to choose well; with x descriptors it only considers screen density and ignores layout.

5. Is this the same as setting width and height attributes?

No. Width and height attributes tell the browser the image's shape so it can reserve space before the file arrives, which prevents layout shift. They do not change which file is downloaded. Oversized dimensions are about sending too many pixels for the slot. A page can have perfect width and height attributes and still send enormous files, or send well-sized files while shifting around. You need both, and each has its own fix.

6. Does resizing images with CSS make the file smaller?

No. CSS such as width 100 per cent or max-width only changes how large the image appears. The browser still downloads the full file at its original pixel dimensions and then scales it down while drawing. To reduce the download you must create smaller files, either in advance with an editor or build tool, automatically through your CMS, or on request through an image CDN, and then point srcset at them.

7. How many image sizes should I generate?

Four to six widths per image is enough for most sites. Too few and some devices get files much larger than they need; too many and you multiply storage and processing, and reduce the chance that a variant is already cached at the CDN. Base the list on your real layout: the narrowest phone slot at the bottom, about twice the widest desktop slot at the top, and roughly even steps between.

See which images send more pixels than they show

The Image Optimisation audit checks every image on your page for file size, format, dimensions, alt text, lazy-loading, layout shift and CDN delivery, and ranks its recommendations by their effect on loading and bandwidth.

Open Image Optimisation Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Image Optimisation Fixes  ·  Fixing Oversized Image Files  ·  Fixing Image CDN Delivery  ·  Fixing Layout Shift from Images  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.