Skip to content

Performance

How to use srcset for responsive images

Without a `srcset`, a phone downloads the same file a desktop does — often several times the pixels it can display. It is wasted bandwidth on exactly the connections least able to spare it.

What 13x checks

This is rule performance.responsive-images in the public registry: Images are served at the size they are displayed. It runs on every audit, against the pages we actually fetched, and its result is derived from the response rather than estimated.

Surface
Performance
Score weight
4 of the readiness score
Scope
Reported as skipped when the page renders only with JavaScript
Applies
To every site

Registry version 2026-07-30. Every rule is published, and the audit is deterministic — the same page produces the same finding every time.

The fix

The same text the audit hands you when this check fails on your own site.

Give the browser more than one size to choose from, so a phone does not download a desktop-width image.

html code
<img
  src="/hero-800.jpg"
  srcset="/hero-400.jpg 400w, /hero-800.jpg 800w, /hero-1600.jpg 1600w"
  sizes="(max-width: 700px) 100vw, 800px"
  width="800"
  height="450"
  alt="Describe the image"
/>

Both attributes are needed and they answer different questions:

- `srcset` lists the files that exist and how wide each one is. - `sizes` tells the browser how wide the image will be *laid out*, which it needs before CSS has been applied in order to pick a file.

Omit sizes and the browser assumes full viewport width, which usually picks the largest file — the opposite of the intent.

Keep width and height on the tag regardless. They reserve the space and prevent the layout shift as the image loads.

To serve a different *crop* rather than a different size, use <picture>:

html code
<picture>
  <source media="(max-width: 700px)" srcset="/hero-square.jpg" />
  <img src="/hero-wide.jpg" width="1600" height="900" alt="Describe the image" />
</picture>

Framework-specific versions

Where the change differs enough to be worth writing out separately.

Does your site have this problem?

13x checks this and 112 others against your live URL in about 30 seconds. No account, and every finding comes with the fix for your framework.

No signup. Results in 30 seconds.

More performance checks