Files
gh-jezweb-claude-skills-ski…/references/format-optimization.md
2025-11-30 08:24:18 +08:00

7.2 KiB

Format Optimization

Complete guide to automatic WebP/AVIF conversion and format selection.


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:

// 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

  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

<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

  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