7.2 KiB
7.2 KiB
Format Optimization
Complete guide to automatic WebP/AVIF conversion and format selection.
format=auto (Recommended)
Automatically serve optimal format based on browser support.
Priority:
- AVIF - Best compression (Chrome, Edge)
- WebP - Good compression (Safari, Firefox)
- Original format - Fallback (older browsers)
Usage:
// URL format
/cdn-cgi/image/width=800,quality=85,format=auto/image.jpg
// Workers format
fetch(imageURL, {
cf: {
image: {
width: 800,
quality: 85,
format: 'auto'
}
}
});
// Cloudflare Images
https://imagedelivery.net/HASH/ID/w=800,q=85,f=auto
Browser Support Detection
Cloudflare automatically checks the Accept header.
Chrome/Edge:
Accept: image/avif,image/webp,image/apng,image/*,*/*
→ Serves AVIF
Safari:
Accept: image/webp,image/apng,image/*,*/*
→ Serves WebP
Older browsers:
Accept: image/jpeg,image/png,image/*,*/*
→ Serves original format (JPEG)
Manual Format Selection
In URL Transformations
<!-- AVIF (best compression) -->
<img src="/cdn-cgi/image/format=avif/image.jpg" />
<!-- WebP (good compression, wide support) -->
<img src="/cdn-cgi/image/format=webp/image.jpg" />
<!-- JPEG (progressive) -->
<img src="/cdn-cgi/image/format=jpeg/image.jpg" />
<!-- Baseline JPEG (older devices) -->
<img src="/cdn-cgi/image/format=baseline-jpeg/image.jpg" />
In Workers
// Get optimal format from Accept header
function getOptimalFormat(request: Request): 'avif' | 'webp' | 'auto' {
const accept = request.headers.get('accept') || '';
if (/image\/avif/.test(accept)) {
return 'avif';
} else if (/image\/webp/.test(accept)) {
return 'webp';
}
return 'auto'; // Cloudflare decides
}
return fetch(imageURL, {
cf: {
image: {
format: getOptimalFormat(request)
}
}
});
Format Comparison
| Format | Compression | Quality | Support | Use Case |
|---|---|---|---|---|
| AVIF | Best (~50% smaller) | Excellent | Modern browsers | First choice (auto) |
| WebP | Good (~30% smaller) | Excellent | Wide support | Fallback from AVIF |
| JPEG | Standard | Good | Universal | Fallback, photos |
| PNG | Lossless | Lossless | Universal | Graphics, transparency |
File Size Example (1920x1080 photo):
- Original JPEG: 500 KB
- WebP: ~350 KB (30% smaller)
- AVIF: ~250 KB (50% smaller)
Progressive vs Baseline JPEG
Progressive JPEG (default):
- Loads in multiple passes (low→high quality)
- Better for slow connections
- Slightly larger file size
Baseline JPEG:
- Loads top-to-bottom
- Better for older devices
- Slightly smaller file size
Usage:
format=jpeg → Progressive JPEG
format=baseline-jpeg → Baseline JPEG
WebP Compression Modes
// Fast compression (faster encoding, larger file)
fetch(imageURL, {
cf: {
image: {
format: 'webp',
compression: 'fast'
}
}
});
// Lossless WebP (no quality loss, larger file)
fetch(imageURL, {
cf: {
image: {
format: 'webp',
compression: 'lossless'
}
}
});
Responsive Images with format=auto
<picture>
<!-- Explicit AVIF for modern browsers -->
<source
type="image/avif"
srcset="
https://imagedelivery.net/HASH/ID/w=480,f=avif 480w,
https://imagedelivery.net/HASH/ID/w=1920,f=avif 1920w
"
/>
<!-- WebP fallback -->
<source
type="image/webp"
srcset="
https://imagedelivery.net/HASH/ID/w=480,f=webp 480w,
https://imagedelivery.net/HASH/ID/w=1920,f=webp 1920w
"
/>
<!-- JPEG fallback -->
<img
srcset="
https://imagedelivery.net/HASH/ID/w=480,f=jpeg 480w,
https://imagedelivery.net/HASH/ID/w=1920,f=jpeg 1920w
"
src="https://imagedelivery.net/HASH/ID/w=1920,f=jpeg"
alt="Responsive image with format fallbacks"
/>
</picture>
<!-- OR: Let format=auto handle it -->
<img
srcset="
https://imagedelivery.net/HASH/ID/w=480,f=auto 480w,
https://imagedelivery.net/HASH/ID/w=1920,f=auto 1920w
"
src="https://imagedelivery.net/HASH/ID/w=1920,f=auto"
alt="Auto-format responsive image"
/>
Quality Recommendations by Format
const qualitySettings = {
jpeg: 85, // Standard for photos
webp: 85, // Same as JPEG
avif: 85, // AVIF efficient at same quality
png: undefined, // Lossless (quality N/A)
graphics: 95 // High quality for logos/text
};
// Photos
/cdn-cgi/image/width=800,quality=85,format=auto/photo.jpg
// Graphics with text
/cdn-cgi/image/width=800,quality=95,format=auto/logo.png
// Thumbnails (lower quality acceptable)
/cdn-cgi/image/width=300,quality=75,format=auto/thumb.jpg
Animation Support
GIF:
format=auto → Still GIF or first frame
anim=true → Preserve animation
Animated WebP:
fetch(animatedGif, {
cf: {
image: {
format: 'webp',
anim: true // Preserve animation
}
}
});
Metadata Handling
Strip metadata (smaller file size):
metadata=none
Keep copyright (default for JPEG):
metadata=copyright
Keep all EXIF (GPS, camera settings):
metadata=keep
Example:
/cdn-cgi/image/width=800,format=auto,metadata=none/photo.jpg
Cost Optimization
- Use format=auto: Smallest files = less bandwidth
- Reasonable quality: 80-85 for photos, 90-95 for graphics
- Strip metadata:
metadata=nonefor public images - Cache at edge: First transformation billable, subsequent free
- WebP animations: Convert GIF to animated WebP (smaller)
Testing Format Support
<script>
// Check AVIF support
const avifSupport = document.createElement('canvas')
.toDataURL('image/avif').indexOf('data:image/avif') === 0;
// Check WebP support
const webpSupport = document.createElement('canvas')
.toDataURL('image/webp').indexOf('data:image/webp') === 0;
console.log('AVIF:', avifSupport); // true in Chrome/Edge
console.log('WebP:', webpSupport); // true in modern browsers
</script>
But: Let Cloudflare handle this with format=auto!
Common Patterns
Hero Image
width=1920,height=1080,fit=cover,quality=85,format=auto,metadata=none
Thumbnail
width=300,height=300,fit=cover,quality=75,format=auto,metadata=none
Avatar
width=200,height=200,fit=cover,gravity=face,quality=90,format=auto
Product Photo
width=800,height=800,fit=contain,quality=90,sharpen=2,format=auto
Blur Placeholder (LQIP)
width=50,quality=10,blur=20,format=webp,metadata=none
Best Practices
- Always use format=auto: Let Cloudflare optimize
- Quality 80-90: Balance file size and quality
- Strip unnecessary metadata: Smaller files
- Test on real devices: Verify format delivery
- Monitor bandwidth: Check Cloudflare Analytics
- Use WebP for animations: Smaller than GIF
- Progressive JPEG for photos: Better perceived load time