Website Spec
PerformanceRequiredUpdated

Image optimisation

Serve images in modern formats (AVIF, WebP), at the right size for the viewport, with explicit dimensions. Images are the largest payload on most pages.

What it is

Image optimisation is the practice of shipping the smallest visually acceptable image for the user’s device. It covers format, dimensions, compression, and how the browser chooses between sources.

<img
  src="hero-800.webp"
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1600.webp 1600w"
  sizes="(max-width: 600px) 100vw, 800px"
  width="800"
  height="450"
  alt="Wide view of the harbour at dusk"
/>

Why it matters

Images are the single largest contributor to page weight on the web — typically 40–50% of total bytes per the HTTP Archive Web Almanac. They are usually the LCP element, so their delivery directly drives Core Web Vitals. Oversized images also waste mobile data, drain battery, and hurt users on slow connections.

How to implement

Use a modern format. Both AVIF and WebP beat JPEG and PNG by 25–50% at equivalent quality, and AVIF is the smaller of the two. Encode AVIF first: it reached Baseline widely available on 25 July 2026, so it is no longer the risky new format you bolt on behind WebP. The remaining trade-off is time, not support — AVIF encodes far more slowly, which matters for user uploads and large batch jobs, but not for a build step that runs once.

Keep the <picture> chain anyway. “Widely available” describes browser versions released over the past two and a half years, not the ones actually installed, and a fallback costs one line:

<picture>
  <source srcset="photo.avif" type="image/avif">
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" width="1200" height="800" alt="…">
</picture>

Treat JPEG XL as an extra source, not a replacement. Chrome 155 (6 October 2026) and Firefox 158 (13 October 2026) turned on JPEG XL decoding, joining Safari, which has supported it since version 17. Shipping in all three engines is not the same as Baseline, though: Edge has not enabled it, so JPEG XL is still limited availability. Nor is it simply a better AVIF. Its strengths lie elsewhere: it can recompress an existing JPEG losslessly into a smaller file and rebuild the original exactly, it decodes progressively, and it holds up at high fidelity. For an ordinary lossy photo at web quality, AVIF is often still the smaller file, so compare the two on your own images. To offer it, add a <source srcset="photo.jxl" type="image/jxl"> to the chain. The browser takes the first type it supports, so put the sources in your order of preference. If you negotiate format on the Accept request header instead, Firefox now lists image/jxl there, and the response needs Vary: Accept so caches keep the variants apart.

Serve responsive sizes. Generate the same image at several widths and let srcset plus sizes pick the right one. A 4000px image in a 400px slot wastes ~99% of the bytes.

Always set width and height. The browser computes the aspect ratio and reserves the slot, preventing CLS when the image loads.

Compress aggressively. Quality 75–80 in WebP is visually indistinguishable from quality 95 for photos. Use tools such as sharp, squoosh, or cwebp.

Strip metadata. EXIF, colour profiles, and thumbnails can add tens of kilobytes per image.

Common mistakes

  • Shipping the original camera JPEG (5MB, 6000px) into a 400px card.
  • PNG for photos. PNG is for graphics with sharp edges and few colours.
  • Omitting width and height, then wondering why CLS is poor.
  • Single fixed src with no srcset — mobile users download the desktop image.
  • Serving an “optimised” image that is still 1MB because compression was set to 100.

Verification

  • DevTools → Network → Img. Sort by size. Anything over 200KB needs a second look.
  • Lighthouse flags “Properly size images” and “Serve images in next-gen formats”.
  • Run Squoosh on the worst offenders and compare.

Related topics

Sources & further reading