Image Optimisation
Also Known As
TL;DR
Explanation
Images typically account for 50-75% of a page's total bytes. Optimisation has several dimensions: format (AVIF is 50% smaller than JPEG at equivalent quality; WebP is 30% smaller; use <picture> for progressive enhancement); compression (lossy vs lossless — most photography tolerates 75-85% quality without visible degradation); responsive sizing (srcset + sizes delivers the appropriately-sized image for each viewport — serving a 2000px image to a 400px mobile screen wastes 80% of the download); lazy loading (defer off-screen images with loading='lazy'); dimensions (explicit width and height prevent layout shift as images load); priority (the LCP image needs fetchpriority='high' and should never be lazy-loaded). CDN image transformation (Cloudflare Images, Imgix, Cloudinary) handles format conversion, resizing, and compression automatically at edge — eliminating most manual optimisation work.
Common Misconception
Why It Matters
Common Mistakes
- Loading the same large image at all viewport sizes — serve appropriately-sized images with srcset/sizes; a mobile user shouldn't download a 2000px image.
- Lazy-loading the LCP (hero) image — delays the most important content and directly harms LCP score.
- No explicit width and height attributes — browser can't reserve space, images shift content as they load (CLS).
- Serving JPEG/PNG when AVIF/WebP is available — modern formats offer 30-50% size reduction at equivalent quality.
- Not setting decoding='async' on large non-LCP images — synchronous decode blocks the main thread.
Avoid When
- Do not lazy-load the LCP (hero) image — it must load as fast as possible.
- Do not apply heavy lossy compression to images where quality is critical (medical imaging, product photography with fine detail).
When To Use
- Apply image optimisation to every image-heavy page — typically the highest ROI performance improvement available.
- Use CDN image transformation (Cloudflare Images, Imgix) to automate format conversion and responsive resizing.
- Use <picture> with AVIF and WebP sources with JPEG/PNG fallback for progressive enhancement across browsers.
Code Examples
<!-- Same large image served to all devices -->
<img src="product-2000px.jpg" alt="Product">
<!-- LCP image lazy-loaded -->
<img src="hero.jpg" alt="Hero" loading="lazy">
<!-- No dimensions — causes CLS -->
<img src="card.jpg" alt="Card">
<!-- LCP hero: eager, high priority, explicit dimensions -->
<img src="hero.jpg" alt="Hero" fetchpriority="high"
width="1200" height="600">
<!-- Responsive image with next-gen format fallback -->
<picture>
<source srcset="product.avif" type="image/avif">
<source srcset="product.webp" type="image/webp">
<img src="product.jpg" alt="Blue ceramic mug"
srcset="product-400.jpg 400w, product-800.jpg 800w"
sizes="(max-width: 600px) 400px, 800px"
loading="lazy" decoding="async"
width="800" height="800">
</picture>