Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.

Use WebP format with fallbacks

Images are served in WebP format with fallbacks for older browsers.

Utilities
Quick take
Typical fix time 15 min
  • WebP provides 25-35% better compression than JPEG/PNG
  • 97%+ browser support—nearly universal
  • Use picture element for older browser fallbacks
  • Supports transparency (like PNG) and animation (like GIF)
Why it matters: WebP is smaller than JPEG and PNG at similar quality—using it reduces page weight by 25-35% for images, improving load times on all devices.

Rule Details

WebP provides excellent compression with near-universal browser support.

Code Example

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

Why It Matters

WebP is smaller than JPEG and PNG at similar quality—using it reduces page weight by 25-35% for images, improving load times on all devices.

Format Comparison

FormatCompressionTransparencyAnimationBrowser Support
WebPExcellentYesYes97%+
JPEGGoodNoNo100%
PNGModerateYesNo100%
GIFPoorYesYes100%

Responsive WebP with Fallback

<picture>
  <!-- WebP for modern browsers -->
  <source
    type="image/webp"
    srcset="
      image-400.webp 400w,
      image-800.webp 800w,
      image-1200.webp 1200w
    "
    sizes="(max-width: 600px) 100vw, 50vw"
  >
 
  <!-- JPEG fallback -->
  <img
    src="image-800.jpg"
    srcset="
      image-400.jpg 400w,
      image-800.jpg 800w,
      image-1200.jpg 1200w
    "
    sizes="(max-width: 600px) 100vw, 50vw"
    alt="Description"
    width="800"
    height="600"
    loading="lazy"
  >
</picture>

Converting to WebP

# Using cwebp (official tool)
cwebp -q 80 input.jpg -o output.webp
 
# Using Sharp
npx sharp-cli input.jpg -o output.webp --quality 80
 
# Using ImageMagick
convert input.jpg -quality 80 output.webp
 
# Batch convert all JPEGs
for f in *.jpg; do cwebp -q 80 "$f" -o "${f%.jpg}.webp"; done

Sharp Node.js Conversion

const sharp = require('sharp')
 
// Single image
async function convertToWebP(input, output, quality = 80) {
  await sharp(input)
    .webp({ quality })
    .toFile(output)
}
 
// With transparency (from PNG)
async function convertPngToWebP(input, output) {
  await sharp(input)
    .webp({
      quality: 80,
      lossless: false, // lossy compression
      alphaQuality: 90 // preserve transparency quality
    })
    .toFile(output)
}

React Picture Component

interface WebPImageProps {
  src: string
  alt: string
  width: number
  height: number
  sizes?: string
  className?: string
  priority?: boolean
}
 
function WebPImage({
  src,
  alt,
  width,
  height,
  sizes,
  className,
  priority
}: WebPImageProps) {
  // Generate WebP path from original
  const webpSrc = src.replace(/\.(jpg|jpeg|png)$/i, '.webp')
 
  return (
    <picture>
      <source type="image/webp" srcSet={webpSrc} />
      <img
        src={src}
        alt={alt}
        width={width}
        height={height}
        sizes={sizes}
        className={className}
        loading={priority ? 'eager' : 'lazy'}
      />
    </picture>
  )
}

Next.js Configuration

// next.config.js
module.exports = {
  images: {
    formats: ['image/webp'], // Prioritize WebP
    // Or include AVIF: ['image/avif', 'image/webp']
  }
}

CSS Background Images

/* Modernizr class approach */
.hero {
  background-image: url('hero.jpg');
}
 
.webp .hero {
  background-image: url('hero.webp');
}
 
/* Or use feature detection */
@supports (background-image: url('test.webp')) {
  .hero {
    background-image: url('hero.webp');
  }
}

Server-Side Content Negotiation

# Nginx configuration
map $http_accept $webp_suffix {
  default "";
  "~*webp" ".webp";
}
 
location ~* ^/images/.+\.(png|jpe?g)$ {
  add_header Vary Accept;
  try_files $uri$webp_suffix $uri =404;
}

Build Pipeline Integration

// Webpack with image-minimizer-webpack-plugin
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
 
module.exports = {
  optimization: {
    minimizer: [
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: 'webp',
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                webp: { quality: 80 }
              }
            }
          }
        ]
      })
    ]
  }
}

Support Notes

  • Image format and delivery behavior can vary by browser, CDN, and device characteristics, so verify the final bytes and rendered output on the supported browser matrix.
  • Add a fallback note when a modern format or loading behavior is not available for every required target browser.

Verification

Automated Checks

  • Test in Safari < 14 (if supporting)—should get JPEG/PNG fallback
  • Run Lighthouse—check "Serve images in modern formats"

Manual Checks

  • Check Network tab—verify WebP is served to supporting browsers
  • Compare file sizes: WebP should be 25-35% smaller
  • Verify visual quality matches original

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Check if images are served in modern formats like WebP with fallbacks for older browsers.

Fix

Auto-fix issues

Convert images to WebP format and implement proper fallback strategies.

Explain

Learn more

Explain how WebP provides 25-35% better compression than JPEG and PNG.

Review

Code review

Review image assets, markup, and delivery configuration related to Use WebP format with fallbacks. Flag exact files or components where format choice, sizing, or loading behavior violates the rule, and describe how to confirm the fix in DevTools.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

Squoosh
squoosh.appTool

Rules that often go hand-in-hand with this one.

Use AVIF format for modern browsers

Images support AVIF format for superior compression with proper browser fallbacks.

Images
Use modern image formats (WebP, AVIF)

Images are served in modern formats (WebP or AVIF) instead of legacy JPEG/PNG where browser support allows, reducing file size without visible quality loss.

Images
Use <picture> with an <img> fallback

Every <picture> element contains a required <img> fallback as its last child, ensuring images display in all browsers including those that don't support <picture>.

Images
Use progressive JPEG encoding

JPEG images use progressive format for better perceived loading performance.

Images

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385