Responsive images with an optimization API

An optimization API creates the candidates. The browser chooses among them. Correct responsive delivery joins deterministic image URLs with accurate srcset, sizes, intrinsic dimensions, and loading priority.

Short answer

Generate a small ladder of widths from the image API, describe those candidates with width descriptors in srcset, and tell the browser the rendered slot width in sizes. Keep the first meaningful image eager, use fetchpriority="high" only for the likely LCP image, and lazy-load images below the fold.

What does the browser need from an image API?

The browser does not know that an API can generate any width. It sees a finite list of candidate URLs. With width descriptors, each candidate declares its intrinsic pixel width. The sizes attribute describes how wide the image slot will be after layout. The browser combines that information with viewport size, device pixel ratio, zoom, and other conditions to choose a candidate.

MDN documents the selection model and the two different problems responsive images solve: resolution switching with srcset and sizes, and art direction with <picture>. Read Using responsive images in HTML for the browser behavior.

A production-ready markup pattern

<img
  src="https://media.example.com/card/w_960/photo.jpg"
  srcset="
    https://media.example.com/card/w_480/photo.jpg 480w,
    https://media.example.com/card/w_720/photo.jpg 720w,
    https://media.example.com/card/w_960/photo.jpg 960w,
    https://media.example.com/card/w_1440/photo.jpg 1440w"
  sizes="(max-width: 680px) calc(100vw - 40px),
         (max-width: 1100px) 50vw,
         520px"
  width="1440"
  height="960"
  loading="lazy"
  decoding="async"
  alt="..." />

The candidate URLs above are illustrative. Map them through your provider SDK or URL builder. The important part is that each URL really returns the width declared beside it.

How many width candidates should you generate?

Start from the layout, not device names. Identify the smallest and largest rendered slots, account for common device pixel ratios, then choose a geometric or design-token ladder. A typical content site might need five to eight widths across all components, not a different width for every viewport pixel.

Control cardinality: let components request widths from an allowlist such as 320, 480, 720, 960, 1280, and 1600. This makes cache behavior and cost easier to predict.

Do not automatically include a 2x candidate if the source cannot support it or the slot is already very large. A 1600 CSS-pixel hero on a 2x screen would imply 3200 source pixels. The visual benefit may not justify the bytes.

What belongs in sizes?

sizes describes the image slot, not the file. Match it to the actual CSS layout. If a two-column card becomes one column below 680px, express that. If the content column stops growing at 1120px, avoid a blanket 100vw that tells the browser the image is wider than it will render.

Use browser developer tools to compare the rendered width with currentSrc and the chosen candidate. Resize the viewport, test at different device pixel ratios, and confirm the browser is not routinely downloading a candidate far larger than the rendered slot.

When should you use picture?

Use <picture> for art direction or an explicit format fallback that the URL service cannot negotiate. Art direction means the composition changes, such as a wide scene on desktop and a portrait crop on mobile. It is not merely a smaller copy of the same crop.

<picture>
  <source
    media="(max-width: 680px)"
    srcset="/media/portrait/w_480/photo 480w,
            /media/portrait/w_720/photo 720w"
    sizes="calc(100vw - 40px)" />
  <img
    src="/media/landscape/w_1280/photo"
    srcset="/media/landscape/w_720/photo 720w,
            /media/landscape/w_1280/photo 1280w"
    sizes="min(1120px, 100vw - 56px)"
    width="1600" height="900" alt="..." />
</picture>

Loading priority rules

  • Do not lazy-load the likely LCP image.
  • Use fetchpriority="high" for one high-value image when the browser would otherwise discover or prioritize it late.
  • Lazy-load images that begin outside the viewport.
  • Include width and height or an aspect ratio so layout does not wait for image metadata.
  • Keep critical images discoverable in server-rendered HTML when possible.

MDN documents HTMLImageElement properties including loading, dimensions, srcset, and fetch priority. web.dev also documents responsive image preloads and browser-level lazy loading.

How do automatic format and responsive width interact?

They solve different choices. The width ladder lets the browser choose pixel dimensions. Automatic format lets the delivery service choose an encoding compatible with the request. Automatic quality lets the service choose encoding settings. Keep those decisions independent in your application contract, even if a vendor encodes them in one delivery URL.

Cloudinary documents responsive delivery options alongside automatic format and quality in its image optimization guide. Treat provider-specific automatic width features carefully: browser-native srcset remains explicit, portable, and easy to inspect.

Verify the responses

If the browser chooses an unexpected file, use the image API debugging runbook. For the server-side contract, return to the practical API guide.

Share with