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

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.

Utilities
Quick take
Typical fix time 20 min
  • WebP is ~25-35% smaller than JPEG at equivalent quality (per web.dev)
  • AVIF is ~40-50% smaller than JPEG at equivalent quality (per web.dev)
  • Use `<picture>` with `<source type="image/avif">` and `<source type="image/webp">` plus an `<img>` fallback
  • WebP has 97%+ global browser support; AVIF is supported in all modern browsers as of 2023
Why it matters: Images are typically 50%+ of page weight. Switching from JPEG to WebP alone reduces transfer sizes by 25-35% with no visible quality change, directly improving Largest Contentful Paint (LCP) and saving bandwidth for users on mobile data plans. These savings compound across every visitor and every image on the site.

Rule Details

WebP and AVIF are modern image formats that achieve smaller file sizes than JPEG and PNG at equivalent visual quality. Using them with proper fallbacks is safe and impactful.

Code Example

<!-- ❌ Bad: Legacy JPEG only -->
<img src="photo.jpg" alt="Mountain landscape">
 
<!-- ✅ Good: AVIF → WebP → JPEG fallback chain -->
<picture>
  <!-- Best compression, modern browsers -->
  <source
    type="image/avif"
    srcset="photo.avif"
  >
  <!-- Good compression, broad support -->
  <source
    type="image/webp"
    srcset="photo.webp"
  >
  <!-- Universal fallback -->
  <img
    src="photo.jpg"
    alt="Mountain landscape"
    width="800"
    height="600"
    loading="lazy"
  >
</picture>

Why It Matters

Images are typically 50%+ of page weight. Switching from JPEG to WebP alone reduces transfer sizes by 25-35% with no visible quality change, directly improving Largest Contentful Paint (LCP) and saving bandwidth for users on mobile data plans. These savings compound across every visitor and every image on the site.

Format Overview

FormatBest Forvs JPEGBrowser Support
AVIFPhotos, graphics~40-50% smallerChrome 85+, Firefox 93+, Safari 16.4+
WebPPhotos, graphics, transparent~25-35% smaller97%+ global (Chrome, Firefox, Safari, Edge)
JPEGPhotos (legacy fallback)BaselineUniversal
PNGTransparency (legacy fallback)LargerUniversal
SVGIcons, illustrationsN/A — vectorUniversal

Source: web.dev — Serve images in modern formats (opens in new tab)

Responsive + Modern Format Combined

Combine format selection with responsive sizes for maximum efficiency.

<picture>
  <source
    type="image/avif"
    srcset="
      photo-400.avif  400w,
      photo-800.avif  800w,
      photo-1200.avif 1200w
    "
    sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 600px"
  >
  <source
    type="image/webp"
    srcset="
      photo-400.webp  400w,
      photo-800.webp  800w,
      photo-1200.webp 1200w
    "
    sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 600px"
  >
  <img
    src="photo-800.jpg"
    srcset="
      photo-400.jpg  400w,
      photo-800.jpg  800w,
      photo-1200.jpg 1200w
    "
    sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 600px"
    alt="Mountain landscape"
    width="1200"
    height="800"
    loading="lazy"
  >
</picture>

Converting Images with Sharp

// scripts/convert-to-modern-formats.mjs
import sharp from 'sharp'
import { globSync } from 'glob'
import path from 'path'
 
const images = globSync('public/images/**/*.{jpg,jpeg,png}')
 
for (const imgPath of images) {
  const { dir, name } = path.parse(imgPath)
 
  // Generate WebP
  await sharp(imgPath)
    .webp({ quality: 80 })
    .toFile(path.join(dir, `${name}.webp`))
 
  // Generate AVIF (slower to encode but smallest output)
  await sharp(imgPath)
    .avif({ quality: 60, effort: 6 })
    .toFile(path.join(dir, `${name}.avif`))
 
  console.log(`Converted: ${name}`)
}

CSS Background Images

/* ❌ No format negotiation — JPEG served to all browsers */
.hero {
  background-image: url('/images/hero.jpg');
}
 
/* ✅ WebP for supporting browsers, JPEG fallback */
.hero {
  background-image: url('/images/hero.jpg'); /* Fallback */
}
 
@supports (background-image: url('test.webp')) {
  .hero {
    background-image: url('/images/hero.webp');
  }
}
Good to Know

For CSS background images, a CDN like Cloudflare, Imgix, or Cloudinary can serve the optimal format automatically based on the Accept header, eliminating the need for @supports queries entirely.

Next.js

Next.js <Image> automatically serves WebP and AVIF to supported browsers without any extra markup.

import Image from 'next/image'
 
// next/image serves WebP/AVIF automatically based on browser Accept header
function Hero() {
  return (
    <Image
      src="/images/hero.jpg" // Next.js converts this automatically
      alt="Hero image"
      width={1200}
      height={600}
      priority
      sizes="100vw"
    />
  )
}
 
// Configure quality in next.config.js
// module.exports = {
//   images: {
//     formats: ['image/avif', 'image/webp'],
//     qualities: [60, 75, 85, 90, 95],
//   }
// }

Verifying Format Delivery

// Check which format browsers are actually receiving
// In Chrome DevTools → Network → filter "Img" → check "Type" column
// Should show "webp" or "avif", not "jpeg"
 
// Or check the Content-Type response header:
// Content-Type: image/webp
// Content-Type: image/avif

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

  • Open Chrome DevTools → Network → filter by "Img" → check the "Type" column—it should show "webp" or "avif"
  • Run Lighthouse — the "Serve images in modern formats" audit flags JPEG/PNG images that could be WebP
  • Test in Safari (to verify JPEG fallback works) by checking Network tab for image format

Manual Checks

  • Use Squoosh to compare file sizes visually at the same quality setting

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

Scan all <img> elements and CSS background-image declarations in this codebase. Identify: 1) Any <img src> pointing to .jpg, .jpeg, or .png files (not served via a CDN that auto-negotiates format). 2) Any <picture> elements that lack <source type="image/webp"> or <source type="image/avif"> entries. 3) Any CSS background images using JPEG or PNG when a WebP equivalent could be used. Report each finding with file path and line number.

Fix

Auto-fix issues

For each image not using modern formats: 1) Convert to WebP at 80% quality using Squoosh or Sharp. 2) Optionally also generate AVIF at 60% quality for browsers that support it. 3) Wrap the original <img> in a <picture> element and add <source type="image/avif"> and <source type="image/webp"> entries with the new files. 4) Keep the original JPEG/PNG as the <img src> fallback. For CSS background images, use a @supports (background-image: url('.webp')) { } query to serve WebP to supporting browsers.

Explain

Learn more

Explain the compression advantages of WebP and AVIF over JPEG and PNG. According to web.dev, WebP lossless images are 26% smaller than PNG and WebP lossy images are 25-35% smaller than JPEG at equivalent visual quality. AVIF offers further improvements: roughly 40-50% smaller than equivalent JPEG. Explain browser support: WebP has 97%+ global browser support as of 2024. AVIF is supported in Chrome 85+, Firefox 93+, and Safari 16.4+. The <picture> element with fallbacks means there is no risk in adopting these formats today.

Review

Code review

Review image assets, markup, and delivery configuration related to Use modern image formats (WebP, AVIF). 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.

AVIF has landed — web.dev

by web.dev

web.devArticle
WebP — MDN Web Docs

by MDN

developer.mozilla.orgDocs
AVIF — MDN Web Docs

by MDN

developer.mozilla.orgDocs
Squooshsquoosh.appTool
Sharpsharp.pixelplumbing.comTool
caniuse — WebPcaniuse.comTool
caniuse — AVIFcaniuse.comTool

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

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
Keep image file sizes within recommended limits

Individual image files are compressed to reasonable sizes to avoid wasted bandwidth and slow load times, especially on mobile networks.

Images
Optimise images for faster loading

All images are compressed and metadata-stripped before deployment, removing unnecessary bytes without visible quality loss.

Images
Use WebP format with fallbacks

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

Images

Was this rule helpful?

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

Loading feedback...
0 / 385