1. srcset + sizes

Browser chooses appropriate file.

Img
Demo landscape

Resize viewport in devtools to test.

<img
  src="fallback.jpg"
  srcset="small.jpg 400w, large.jpg 800w"
  sizes="(max-width: 600px) 100vw, 400px"
  alt="..."
>

2. loading=lazy

Defers network until near viewport.

Lazy
Lazy loaded

Check Network panel when scrolling.

<img src="photo.jpg" alt="..." loading="lazy" decoding="async">

3. picture art direction

Different crops per breakpoint.

Note

Use <picture> with media on <source> for crop swaps.

WebP sources with JPEG fallback.

<picture>
  <source media="(min-width: 48rem)" srcset="wide.webp">
  <img src="narrow.jpg" alt="">
</picture>

Frequently asked questions

When not to lazy load?
Skip lazy on LCP hero image. Use fetchpriority=high instead.
sizes wrong symptom?
Browser may download too large a file. Match real CSS layout width.
WebP in srcset?
Yes. List type per file; browser picks first supported.