Back to insights
Five wooden picture frames of the same savanna tree, graded from small to large along a shelf. The middle one, in amber, is being lowered on a hook into a recess in the wall that it fits exactly.

Responsive Images: Most Sites Use srcset, Many Get sizes Wrong

Leave out one attribute and the browser assumes every image fills the whole screen. We tested it on our own Insights page: with the attribute removed, a desktop browser downloaded 3.2 times the image data for a page that looked exactly the same.

In our Core Web Vitals post, step three was “send the right number of pixels.” That sounds like a resizing job. Mostly it is a markup job. You can export a perfect set of widths and still have the browser fetch the biggest one, because it picks a file before your CSS has loaded and has no idea how wide the image will be on the page. You have to tell it, and the attribute that does is sizes.

If you do not write HTML yourself, this still applies to you: your theme or CMS writes this markup on your behalf. The measurement below shows what it costs when it gets it wrong, and the checklist at the end shows how to check yours without reading any code.

How the browser picks a file

A responsive image has three parts:

<img
  src="hero-1080.jpg"
  srcset="hero-640.jpg 640w,
          hero-1080.jpg 1080w,
          hero-1920.jpg 1920w"
  sizes="(width <= 768px) 100vw, 50vw"
  width="1920" height="1280"
  alt="...">
  • srcset lists the files you have and how wide each one is in real pixels. The unit is w, not px.
  • sizes tells the browser how wide the image will be in the layout at each screen width. The first condition that matches wins.
  • src is the fallback for anything that ignores the other two.

The browser takes the slot width from sizes, multiplies it by the screen’s pixel density, and looks for a file at least that wide. Pixel density, or device pixel ratio, is how many real pixels a screen packs into each pixel of your layout: 2 on most laptops and phones, so an image shown 300 pixels wide needs a 600 pixel file to look sharp. If nothing matches exactly, MDN says it “will choose the first image that is bigger than the chosen slot size and scale it down to fit.”

The detail that catches people: if sizes is missing, it defaults to 100vw, the full width of the viewport. An image sitting in a 50% column gets treated as full width, and the browser fetches a file twice as wide as it needs.

How common the mistake is

The HTTP Archive Web Almanac measures this across millions of pages. Its latest media chapter is the 2024 edition; the 2025 one has not been published yet.

MeasureMobileDesktop
srcset using w descriptors62%64%
Median sizes error, too large16%43%
75th percentile sizes error94%168%
sizes wrong enough to change the file chosen14%20%
Estimated wasted image data, 75th percentile page55 KB179 KB
Estimated wasted image data, 90th percentile page400 KB920 KB

Adoption is going the right way: 42% of mobile pages now use srcset, up from 34% in 2022. Accuracy is not. The median desktop sizes error more than doubled over the same period. The Almanac estimates that about a quarter of desktop pages using w descriptors waste 180 KB or more, and is careful to call that an estimate, because its crawler never loaded the files a correct sizes would have picked.

It also found that on half of pages, the largest image has more pixels than a mobile viewport can display.

What it costs: we measured our own page

Rather than calculate it, we tested it on our own Insights page. Each post card there shows its artwork 294 pixels wide on a desktop screen, and our markup gives the browser a correct sizes. In Chrome, at a 1440 pixel window on a 2x screen, we loaded every card image twice: once with our sizes, and once with it removed, which is what happens on any site that leaves it out.

  • Needed: 588 real pixels wide (a 294 pixel card on a 2x screen)
  • With sizes: the 750 pixel file, 19.8 KB
  • Without sizes: the 1,536 pixel file, 84.9 KB
One card from our Insights page, drawn to scale. Same card on screen, more than four times the download. Measured in Chrome at a 1440 pixel window, 8 November 2026.

With sizes, the browser works out that it needs 588 real pixels and picks the 750 pixel file. Without it, it assumes the card fills the whole 1,440 pixel window, needs 2,880, and takes the largest file on offer, which here is the 1,536 pixel original. The card on screen is identical either way.

Post cardWith sizesWithout
Responsive images19.8 KB84.9 KB
Removing EXIF data20.7 KB80.5 KB
Core Web Vitals9.8 KB28.6 KB
AI search and images15.9 KB65.0 KB
Is SEO dead?18.8 KB54.0 KB
WebP vs JPEG vs PNG13.8 KB32.0 KB
Alt text examples13.1 KB33.7 KB
Batch renaming16.8 KB35.8 KB
Image SEO and rankings11.1 KB34.1 KB
All nine139.6 KB448.6 KB

That is 3.2 times the image data, and 309 KB that nobody ever sees, for a page whose layout did not change at all.

Two caveats. On a phone there was no difference, because below 640 pixels our cards run the full width, so a missing sizes and a correct one say the same thing. The waste is a desktop and tablet problem. And while measuring, one image came back at the large size even with sizes set, because the browser reused a bigger copy it had already downloaded. MDN warns about exactly this when testing; that row uses the reading taken before the cache was warm.

Gaps between your widths cost too. On a phone 390 pixels wide at 3x, a full-width image needs 1,170 real pixels. If your files are 640, 1080 and 1920 pixels wide, the next one up is 1920, about 2.7 times the pixels needed. That one is arithmetic rather than a measurement, and it is why the number of widths matters as much as the attribute.

How many widths you actually need

No standard sets a number. This is how we would work it out, and it is a judgement rather than a rule.

  1. Start from your layout, not from a list of devices. Work out the widest slot each kind of image fills: a full-bleed hero, a half-width card, a thumbnail. That is the width that matters for each one.
  2. Multiply by pixel density. Most phones are 2x or 3x, so a full-width image on a 390 pixel phone wants 780 to 1,170 real pixels.
  3. Close the gaps that cost the most. In the phone example, adding a 1280 file saves far more than adding a 2560.
  4. Consider stopping at 2x. In a photograph, few people can see the difference between 2x and 3x, and capping it saves bytes on every high-end phone.
  5. Stop at your widest real slot. If your layout never goes wider than 1,440 pixels, a 3,840 pixel file only ever reaches someone zoomed out on a 4K screen.

For most content sites, four or five widths per kind of image covers phones through desktop heroes without big jumps. Something like 640, 1024, 1280, 1600 and 1920 is a reasonable start.

The auto shortcut, and its conditions

Writing sizes by hand is fiddly, and it goes stale every time someone changes the CSS. There is now a shortcut:

<img loading="lazy" sizes="auto"
  width="800" height="533"
  srcset="card-640.jpg 640w,
          card-1024.jpg 1024w,
          card-1280.jpg 1280w"
  src="card-1024.jpg" alt="...">

With auto, MDN says, “the browser should use the expected layout width of the element to select the image to display.” It can, because a lazy image loads after the layout is known. Three conditions come with it.

  • It only works with loading="lazy". Your hero should never be lazy, because that delays Largest Contentful Paint (LCP), the Core Web Vitals measure of when the main image or text finishes appearing. So auto does nothing for your most important image. The Almanac found 9.5% of mobile LCP images are lazy-loaded anyway.
  • Safari does not support it yet. Can I Use puts global support at about 74%: Chrome and Edge from version 126, Firefox from 150, and no version of Safari on Mac or iPhone. List your manual values after it, as in sizes="auto, (width <= 768px) 100vw, 50vw", and browsers without it fall back to those.
  • Set width and height. If the browser cannot work out a layout size, MDN notes it falls back to those attributes, and failing that to a default of 300 by 150.

WordPress has added sizes="auto" to lazy-loaded images on its own since version 6.7, so if you run WordPress, the images below the fold may already be handled.

When you need picture instead

srcset and sizes serve the same picture at different sizes. If you want a different crop on a phone, such as a tight portrait instead of a wide landscape, that is art direction, and it needs picture with a media condition on each source. MDN also warns that once you use media there, you should not put media conditions in sizes as well.

Only 9.3% of mobile pages use picture, against 42% for srcset. That ratio is about right. Most sites need resizing, not recropping.

The checklist

  1. Export several widths of each kind of image, sized to your layout slots and spaced so there are no big jumps.
  2. Write sizes for every srcset that uses w. Leaving it out means 100vw.
  3. Check it against the real layout. No code needed: in Chrome, Edge or Firefox, right-click an image and open it in a new tab, and the tab shows the width of the file that actually loaded. If it is much more than twice the width the image takes up on your page, the browser is being told the wrong size. Developers can confirm it in the network panel of the browser’s developer tools.
  4. Use sizes="auto" with a manual fallback on lazy images below the fold.
  5. Never lazy-load the hero, and write its sizes by hand.
  6. Always set width and height, so the browser can reserve the space and auto has something to fall back on.

Questions people ask

If my images are already compressed, does this matter?

Yes. Compression lowers the bytes per pixel. srcset and sizes decide how many pixels you send. A well-compressed file at twice the width you need is still four times the pixels.

Do small images like icons and logos need srcset?

Use SVG for logos and icons where you can. For a small raster image that is always shown at one size, 1x and 2x descriptors are simpler than w and need no sizes at all.

Can JavaScript pick the right image instead?

Not well. MDN explains that browsers start fetching images before scripts and styles have run, so by the time a script swaps the file, the large one is usually already on its way. That is why this lives in the HTML.

Does Google rank pages higher for using srcset?

Not directly. It matters through page speed, mainly LCP, and through not spending your visitors’ mobile data on pixels they never see. The wider picture is in what actually affects image rankings.

What does Resiqo do about this?

One part of it. Resiqo resizes to a maximum dimension you choose, from 640 to 4,000 pixels, and converts the format, all in your browser, so the originals never leave your device. It exports one size per run, so a full srcset set means one export per width. It does not write your markup or your sizes, which depend on your layout. If your CMS or framework generates the widths for you, as WordPress and Next.js do, Resiqo’s job is the master file you hand it. The format side is in WebP vs JPEG vs PNG.


Sources: HTTP Archive, Web Almanac 2024, Media, for srcset and descriptor adoption, the sizes error percentiles and wasted-data estimates, the oversized largest image, lazy-loaded LCP images and picture usage; MDN, Responsive images, for how the browser picks a candidate, density descriptors, art direction and why a script cannot do the job; MDN, The img element, for the 100vw default, sizes="auto" and its fallback order; Can I Use, sizes=“auto”, for browser support; Make WordPress Core, Auto Sizes for Lazy Loaded Images in WordPress 6.7, for WordPress adding it automatically. The before and after table is our own measurement, taken on this site’s Insights page in Chrome on 8 November 2026, and can be repeated by loading any card image with and without its sizes. The phone gap example is our own arithmetic. Can I Use figures were read on 19 October 2026 and move as browsers ship.