Image Optimisation
Date: 2026-08-16
The largest and most mechanical win available to a retail site. Four changes — right dimensions, right format, responsive sources, correct loading — routinely halve page weight, and none of them requires touching application code.
What it is
Image optimisation is delivering the smallest file that looks right on the device requesting it. Images are usually the majority of a page’s bytes and frequently the LCP element, which makes this the highest-leverage asset work there is.
The four levers, in order of effect
1. Dimensions. The commonest and largest waste is serving a 3000px-wide image into a 400px slot.
3000 × 2000 JPEG, quality 80 ≈ 1,400 KB
800 × 533 JPEG, quality 80 ≈ 110 KB
800 × 533 AVIF, quality 50 ≈ 35 KB
────────
40× smaller than where we started
Serving at 2× the CSS size covers high-DPI screens. Beyond that is invisible and expensive.
2. Format. Modern formats compress substantially better at equivalent perceived quality.
| Format | Use for | Notes |
|---|---|---|
| AVIF | Photographs | Best compression; slower to encode |
| WebP | Photographs, fallback | Broadly supported, good compression |
| JPEG | Final fallback | Universal |
| PNG | Flat colour, transparency | Lossless, large. Rarely right for photos |
| SVG | Logos, icons, illustration | Vector, scales free. Minify it |
<picture> lets the browser choose:
<picture>
<source srcset="/hero.avif" type="image/avif">
<source srcset="/hero.webp" type="image/webp">
<img src="/hero.jpg" width="1200" height="600" alt="…" fetchpriority="high">
</picture>3. Responsive sources. One file for every viewport wastes bytes on small screens.
<img
src="/product-800.jpg"
srcset="/product-400.jpg 400w, /product-800.jpg 800w, /product-1600.jpg 1600w"
sizes="(max-width: 640px) 100vw, 50vw"
width="800" height="600" alt="Merino wool socks">sizes is the part people get wrong — it tells the browser how much space the image will occupy, so it can pick before CSS has been parsed. Get it wrong and the browser picks badly in the direction of too large.
4. Loading behaviour.
<img loading="lazy" decoding="async"> <!-- below the fold -->
<img fetchpriority="high"> <!-- the LCP image. Never lazy -->Lazy-loading the LCP image is a self-inflicted regression and it’s remarkably common, usually because a global lazy-load was applied across a template — Largest Contentful Paint.
Always set width and height
Two reasons, and both matter:
- Cumulative Layout Shift — the browser reserves space from the aspect ratio before the file arrives
- Correct source selection — with
srcset, dimensions help the browser choose
Setting them doesn’t fix the displayed size; CSS still controls that. height: auto in CSS keeps the aspect ratio while the attributes do their job.
Automate it
Hand-optimising doesn’t survive contact with a merchandising team uploading product photos.
- An image CDN — Shopify, Cloudinary, imgix and most CDNs transform on the fly from a URL parameter, negotiating format by
Acceptheader. This is the right answer for retail because it works on images nobody technical ever touches - Build-time pipelines for static assets
- A budget that fails the build when a page’s image weight exceeds a threshold
Alt text
Not performance, but it belongs with the image and gets forgotten:
- Describe the content and its purpose. “Merino wool socks, charcoal” not “image” and not “socks socks wool socks buy”
- Empty
alt=""for decorative images, so screen readers skip them. Omitting the attribute entirely is different and worse — some readers announce the filename - Product images need real alt text. It’s an accessibility requirement and a genuine Technical SEO signal — see The Accessibility Tree
Traps
- Recompressing an already-compressed JPEG adds artefacts without saving much. Optimise from the original
- Quality 90+ is almost never distinguishable from 75–80 and is often double the size
- PNG for photographs — very common, very expensive
- SVGs with embedded raster data, which defeats the point
- Icon fonts where inline SVG would be smaller, cacheable and accessible
- CSS
background-imagefor the LCP element. Invisible to the preload scanner, so discovery is late — Document Parsing