The most surprising thing about modern image formats like WebP and AVIF is how dramatically they can shrink file sizes without a visible loss of quality, making them far superior to JPG and PNG for web use.

Let’s see this in action. Imagine you have a typical website banner image, say hero.jpg, weighing in at 250KB.

# Original image size (example)
ls -lh hero.jpg
-rw-r--r-- 1 user user 250K Jan 1 10:00 hero.jpg

Now, let’s convert it to WebP using a common tool like cwebp.

# Convert to WebP with quality setting 80 (out of 100)
cwebp -q 80 hero.jpg -o hero.webp

# Check the new size
ls -lh hero.webp
-rw-r--r-- 1 user user 75K Jan 1 10:05 hero.webp

We’ve just cut the file size by over 70% while keeping visual fidelity high. AVIF, often even more efficient, can push this further.

# Convert to AVIF with quality setting 30 (out of 63, AVIF's typical range)
avifenc -q 30 hero.jpg hero.avif

# Check the new size
ls -lh hero.avif
-rw-r--r-- 1 user user 55K Jan 1 10:10 hero.avif

AVIF takes it down to about 22% of the original size. This isn’t just about smaller numbers; it directly translates to faster page loads, reduced bandwidth consumption for users, and better SEO scores.

These newer formats leverage advanced compression techniques. WebP uses predictive coding and a color space transformation that’s more efficient than older formats. AVIF builds on this, using the AV1 video codec’s intra-frame prediction, which is incredibly sophisticated at finding redundancies within an image.

To actually use these on a website, you need to tell the browser which format to download. The <picture> element is your best friend here. It allows you to provide multiple sources for an image, and the browser picks the first one it supports.

<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="Hero Image">
</picture>

In this setup, if the user’s browser supports AVIF, it will download hero.avif. If not, but it supports WebP, it will download hero.webp. If both are unsupported, it falls back to the hero.jpg specified in the <img> tag.

But what about images that aren’t immediately visible when the page loads? This is where lazy loading comes in. Instead of downloading every image on the page at once, lazy loading defers the download of off-screen images until the user scrolls near them. This dramatically speeds up initial page load times, especially for pages with many images.

The native browser lazy loading is now widely supported and incredibly simple to implement:

<img src="placeholder.gif" data-src="offscreen-image.jpg" loading="lazy" alt="Offscreen Image">

The loading="lazy" attribute is the key. The browser knows not to fetch offscreen-image.jpg until it’s about to enter the viewport. The src attribute can point to a small, lightweight placeholder image (or even a transparent pixel) to avoid layout shifts while the actual image is loading.

Combining modern formats with lazy loading is a powerful one-two punch for performance. You can even combine them within the <picture> element:

<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="placeholder.gif" data-src="hero.jpg" loading="lazy" alt="Hero Image">
</picture>

Here, the browser will first try to load the AVIF version, then WebP, falling back to JPG, and only load any of them when the user scrolls to reveal the image.

One aspect that often trips people up is the srcset attribute in the <source> and <img> tags. While we’ve used it here for format selection, its primary purpose is actually responsive images. You can provide multiple image files of different sizes and let the browser choose the most appropriate one based on the device’s screen resolution and viewport size. For example:

<img srcset="image-small.jpg 480w,
             image-medium.jpg 800w,
             image-large.jpg 1200w"
     sizes="(max-width: 600px) 480px,
            (max-width: 900px) 800px,
            1200px"
     src="image-medium.jpg"
     alt="Responsive Image">

Here, srcset lists image files and their intrinsic widths (w descriptor). sizes tells the browser how wide the image will be displayed at different viewport widths. The browser then uses this information to pick the best srcset candidate to download, preventing a small phone from downloading a massive desktop-sized image. When you combine srcset for responsive sizing with <source> elements for format negotiation, you’re building a truly robust and performant image delivery system.

The next step after mastering image formats and lazy loading is understanding image CDNs and their advanced optimization features.

Want structured learning?

Take the full Performance course →