# Format Optimization Complete guide to automatic WebP/AVIF conversion and format selection. --- ## format=auto (Recommended) Automatically serve optimal format based on browser support. **Priority**: 1. **AVIF** - Best compression (Chrome, Edge) 2. **WebP** - Good compression (Safari, Firefox) 3. **Original format** - Fallback (older browsers) **Usage**: ```typescript // 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 ```html ``` ### In Workers ```typescript // 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 ```typescript // 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 ```html Responsive image with format fallbacks Auto-format responsive image ``` --- ## Quality Recommendations by Format ```typescript 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**: ```typescript 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 1. **Use format=auto**: Smallest files = less bandwidth 2. **Reasonable quality**: 80-85 for photos, 90-95 for graphics 3. **Strip metadata**: `metadata=none` for public images 4. **Cache at edge**: First transformation billable, subsequent free 5. **WebP animations**: Convert GIF to animated WebP (smaller) --- ## Testing Format Support ```html ``` **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 1. **Always use format=auto**: Let Cloudflare optimize 2. **Quality 80-90**: Balance file size and quality 3. **Strip unnecessary metadata**: Smaller files 4. **Test on real devices**: Verify format delivery 5. **Monitor bandwidth**: Check Cloudflare Analytics 6. **Use WebP for animations**: Smaller than GIF 7. **Progressive JPEG for photos**: Better perceived load time --- ## Official Documentation - **Transform via URL**: https://developers.cloudflare.com/images/transform-images/transform-via-url/ - **Supported Formats**: https://developers.cloudflare.com/images/transform-images/#supported-formats-and-limitations