<picture> <!-- AVIF: best compression for browsers that support it --> <source srcset="hero-image.avif" type="image/avif"> <!-- WebP: fallback for browsers without AVIF support --> <source srcset="hero-image.webp" type="image/webp"> <!-- JPEG/PNG: final fallback for legacy browsers --> <img src="hero-image.jpg" alt="Your descriptive alt text here" width="1920" height="1080">
</picture>
<picture> <!-- AVIF: best compression for browsers that support it --> <source srcset="hero-image.avif" type="image/avif"> <!-- WebP: fallback for browsers without AVIF support --> <source srcset="hero-image.webp" type="image/webp"> <!-- JPEG/PNG: final fallback for legacy browsers --> <img src="hero-image.jpg" alt="Your descriptive alt text here" width="1920" height="1080">
</picture>
<picture> <!-- AVIF: best compression for browsers that support it --> <source srcset="hero-image.avif" type="image/avif"> <!-- WebP: fallback for browsers without AVIF support --> <source srcset="hero-image.webp" type="image/webp"> <!-- JPEG/PNG: final fallback for legacy browsers --> <img src="hero-image.jpg" alt="Your descriptive alt text here" width="1920" height="1080">
</picture>
# Standard lossy WebP at quality 80
cwebp -q 80 input.jpg -o output.webp # Lossless WebP (for graphics with transparency)
cwebp -lossless input.png -o output.webp # Batch encode all JPEGs in a directory
for f in *.jpg; do cwebp -q 80 "$f" -o "${f%.jpg}.webp"; done
# Standard lossy WebP at quality 80
cwebp -q 80 input.jpg -o output.webp # Lossless WebP (for graphics with transparency)
cwebp -lossless input.png -o output.webp # Batch encode all JPEGs in a directory
for f in *.jpg; do cwebp -q 80 "$f" -o "${f%.jpg}.webp"; done
# Standard lossy WebP at quality 80
cwebp -q 80 input.jpg -o output.webp # Lossless WebP (for graphics with transparency)
cwebp -lossless input.png -o output.webp # Batch encode all JPEGs in a directory
for f in *.jpg; do cwebp -q 80 "$f" -o "${f%.jpg}.webp"; done
# Quality 60, speed 6 (good balance of speed and compression)
avifenc --speed 6 -q 60 input.jpg output.avif # Best compression (slow — use for pre-built assets only)
avifenc --speed 0 -q 60 input.jpg output.avif # Faster encoding (speed 8 — 30% less compression than speed 0)
avifenc --speed 8 -q 60 input.jpg output.avif # Batch encode with GNU parallel (4 cores, adjust -j to core count)
ls *.jpg | parallel -j 4 avifenc --speed 6 -q 60 {} {.}.avif
# Quality 60, speed 6 (good balance of speed and compression)
avifenc --speed 6 -q 60 input.jpg output.avif # Best compression (slow — use for pre-built assets only)
avifenc --speed 0 -q 60 input.jpg output.avif # Faster encoding (speed 8 — 30% less compression than speed 0)
avifenc --speed 8 -q 60 input.jpg output.avif # Batch encode with GNU parallel (4 cores, adjust -j to core count)
ls *.jpg | parallel -j 4 avifenc --speed 6 -q 60 {} {.}.avif
# Quality 60, speed 6 (good balance of speed and compression)
avifenc --speed 6 -q 60 input.jpg output.avif # Best compression (slow — use for pre-built assets only)
avifenc --speed 0 -q 60 input.jpg output.avif # Faster encoding (speed 8 — 30% less compression than speed 0)
avifenc --speed 8 -q 60 input.jpg output.avif # Batch encode with GNU parallel (4 cores, adjust -j to core count)
ls *.jpg | parallel -j 4 avifenc --speed 6 -q 60 {} {.}.avif
const sharp = require('sharp'); // v0.33.x // WebP
await sharp('input.jpg') .webp({ quality: 80 }) .toFile('output.webp'); // AVIF
await sharp('input.jpg') .avif({ quality: 60, speed: 6 }) .toFile('output.avif');
const sharp = require('sharp'); // v0.33.x // WebP
await sharp('input.jpg') .webp({ quality: 80 }) .toFile('output.webp'); // AVIF
await sharp('input.jpg') .avif({ quality: 60, speed: 6 }) .toFile('output.avif');
const sharp = require('sharp'); // v0.33.x // WebP
await sharp('input.jpg') .webp({ quality: 80 }) .toFile('output.webp'); // AVIF
await sharp('input.jpg') .avif({ quality: 60, speed: 6 }) .toFile('output.avif');
// vite.config.js
import { imagetools } from 'vite-imagetools'; // v6.x export default { plugins: [imagetools()]
}; // Usage in component — browser picks the best format it supports
import heroAvif from './hero.jpg?format=avif&quality=60';
import heroWebp from './hero.jpg?format=webp&quality=80';
// vite.config.js
import { imagetools } from 'vite-imagetools'; // v6.x export default { plugins: [imagetools()]
}; // Usage in component — browser picks the best format it supports
import heroAvif from './hero.jpg?format=avif&quality=60';
import heroWebp from './hero.jpg?format=webp&quality=80';
// vite.config.js
import { imagetools } from 'vite-imagetools'; // v6.x export default { plugins: [imagetools()]
}; // Usage in component — browser picks the best format it supports
import heroAvif from './hero.jpg?format=avif&quality=60';
import heroWebp from './hero.jpg?format=webp&quality=80'; - Alpha channel transparency — full 8-bit alpha, works in both lossy and lossless modes
- Animation — frame-by-frame animation with full color depth (24-bit vs GIF's 8-bit)
- Metadata — EXIF and XMP embedding - HDR and wide color gamut — 10-bit and 12-bit color depth, Rec. 2020 and DCI-P3 color spaces, PQ and HLG transfer functions. HDR images in AVIF retain luminance headroom that WebP loses at 8-bit.
- Film grain synthesis — encode film grain as metadata rather than data, reducing file size for grainy images
- Progressive decoding (via sequences) — AVIF sequences can deliver a low-resolution version first
- Lossless mode — less common than WebP lossless but available - User-generated content platforms — images are uploaded constantly, must be processed quickly
- Dynamic resizing pipelines — on-demand image transforms where latency matters
- Real-time applications — screen sharing, video conferencing, live media - Speed of encoding matters. CI/CD pipelines, user uploads, real-time image processing, or any workflow where encoding time affects latency or throughput.
- Your CDN handles image transforms. Most CDNs serve WebP from JPEG/PNG originals on-the-fly. AVIF transform support is less universal and often slower.
- You want maximum compatibility. 97% browser coverage, universal toolchain support, no edge cases.
- You are replacing JPEG or PNG for standard web content. Hero images, thumbnails, blog post images, UI assets — WebP covers all of these well.
- Animation is needed. Animated WebP is widely supported; animated AVIF is still catching up.
- Build-time constraints exist. Short CI budgets or small build servers make AVIF batch encoding impractical. - Maximum compression is the priority. High-traffic pages where bandwidth cost is measurable — e-commerce category pages, news homepages, large media galleries. A 20% reduction in image bytes translates to lower CDN costs and better LCP at scale.
- HDR content is in your pipeline. AVIF is the only web format that correctly handles 10-bit and 12-bit HDR imagery with PQ or HLG transfer functions. If you are serving content for HDR displays, AVIF is the only format that preserves what you shot.
- Encoding is a one-time cost. Static marketing sites, landing pages, or blog posts where images are set once and rarely change — encoding time is front-loaded and amortized across thousands of page views.
- You have encoding hardware to spare. AVIF parallelizes well across CPU cores. An 8-core server cuts encoding time roughly in half. GPU-accelerated AV1 encoders (Intel Arc, AMD RDNA 3+, NVIDIA Ada) reduce it further.
- You are forward-building. AVIF's trajectory is positive — libaom encoders get faster with every release. - WebP for all images by default. Encode your full image library to WebP. This covers 97% of users with fast encoding and solid compression.
- AVIF additionally for high-value, high-traffic images. Identify your top 10–20% of images by page views — hero images, product shots, above-the-fold content. Encode these to AVIF and serve with the <picture> pattern. The encoding cost is bounded; the bandwidth savings are significant.
- Measure the delta. Check your CDN transfer reports before and after AVIF deployment. On a site serving 500 GB/month in images, a 25% reduction saves ~125 GB — real money at CDN prices.