Fixing Wrong Image Dimensions
An image has two sizes: the pixels stored in the file and the space it fills on screen. When the file is 3,000 pixels wide and the slot is 360, a phone downloads roughly seventy times more pixels than it can show, then throws them away. This is the finding reported as wrong or oversized image dimensions.
It is separate from layout shift, which is about reserving space. This guide shows how to measure the size each image is really displayed at, decide which widths to generate, and write srcset and sizes so every screen gets a file that fits.
Large image dimensions waste bytes even when the file is compressed well.
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:
- Intrinsic size: the width and height stored in the file itself. In developer tools,
hover over the image source in the Elements panel, or look at
naturalWidthin the console. - Rendered size: the width and height the image occupies in the layout, in CSS pixels. Developer tools show this as the element's box size.
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.
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.
| Mistake | What happens | Fix |
|---|---|---|
No sizes at all | Browser assumes 100vw and fetches a file sized
for the full screen width. | Add a sizes value describing the real slot. |
| Conditions in the wrong order | The 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 vw | Percentages are not allowed in sizes
and the value is ignored. | Use vw, px, em or calc(). |
Copying one sizes to every template | Thumbnails 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 file | Browser 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
- CSS background images.
srcsetdoes not apply to backgrounds. Useimage-set()with resolution descriptors, or media queries that swap the URL at breakpoints. - Images scaled with object-fit. An image cropped with
object-fit: coverinto a tall box can need more width than the box suggests, because only part of the image is visible. Base yoursizeson the scaled image, not just the box. - Zoomable product images. A zoom or lightbox view needs a large file, but it should
be loaded only when the visitor opens it, not in the initial
srcset. - SVG. Vector images have no fixed pixel size and never need
srcset. Check that SVG files do not embed large bitmaps, which some design tools do. - Retina screenshots. Screenshots taken on a high-density screen are often twice the width you expect. Export them at the display size you need, plus a 2x version if the text must stay crisp.
- Open Graph images. Social share images have their own recommended dimensions and are never shown in your page layout, so they are not part of this finding.
Keeping dimensions in check
- Cap uploads. Set a maximum width at upload, in the CMS or the build step, so an unedited camera file never reaches the public site.
- Own sizes in components. Put
srcsetandsizesin the component or template that outputs each kind of image, so a card, a hero and a thumbnail each describe their own slot. - Update sizes with the layout. When a redesign changes a column width, update the
sizesvalue in the same change. - Keep masters. Store full-resolution originals outside the web root so you can regenerate variants later without quality loss.
- Re-audit key templates. Run the Image Optimisation audit on your home page, a category page and an article after each layout change.
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.
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 โ