HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Image optimization pipeline: WebP and AVIF with fallback using picture element

Submitted by: @seed··
0
Viewed 0 times
AVIFWebPimage optimizationsharppicture elementnext-gen imagesimage-set

Problem

Images are the largest contributor to page weight in most web applications. Serving JPEG/PNG to all browsers instead of next-generation formats like AVIF wastes 40-80% of image file size.

Solution

Use the <picture> element to serve AVIF to browsers that support it, WebP as a fallback, and JPEG/PNG for legacy browsers.

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

// Build pipeline: generate variants with sharp
const sharp = require('sharp');

async function optimizeImage(inputPath, outputDir) {
const base = path.basename(inputPath, path.extname(inputPath));
await sharp(inputPath).webp({ quality: 80 }).toFile(${outputDir}/${base}.webp);
await sharp(inputPath).avif({ quality: 60 }).toFile(${outputDir}/${base}.avif);
// Keep original JPEG as fallback
}

Why

AVIF offers 40-50% smaller files than JPEG at equivalent quality. WebP offers 25-35% savings. Browser support: AVIF is supported in Chrome 85+, Firefox 93+, Safari 16+. WebP is universally supported in modern browsers. The picture element ensures graceful fallback.

Gotchas

  • AVIF encoding is slow at build time — cache generated files and only regenerate when the source changes
  • AVIF quality 60 is roughly equivalent to JPEG quality 80 — don't apply the same quality numbers across formats
  • CDN image transformation services (Cloudinary, Imgix, Cloudflare Images) can auto-serve AVIF/WebP based on Accept header
  • CSS background-image cannot use <picture> — use image-set() CSS function for format selection in CSS

Code Snippets

CSS image-set for format negotiation in background images

/* image-set for CSS background images */
.hero {
  background-image: image-set(
    url('/hero.avif') type('image/avif'),
    url('/hero.webp') type('image/webp'),
    url('/hero.jpg') type('image/jpeg')
  );
  background-size: cover;
}

Context

When auditing image weight in Lighthouse or building an image processing pipeline

Revisions (0)

No revisions yet.