Darek Kay's picture
Darek Kay
Solving web mysteries

Web developer's guide to AVIF images

AVIF (AV1 Image File Format) is a royalty-free image format that usually performs better than other popular alternatives (JPEG, PNG, WebP). With Chrome 85+ and Firefox 93+, the browser support is getting better, so it is now worth including AVIF images on web pages.

Example image

In the following, I've encoded the same image using JPEG, WebP and AVIF (if you can't see all three images, your browser might not support a certain format):

JPEG (30 kB)
WebP (15 kB)
AVIF (9 kB)

Although the image quality is subjectively similar, the file size difference is clear:

FormatFile sizeSmaller than JPEG
JPEG30 kB-
WebP15 kB50%
AVIF9 kB70%

A smaller file size means a faster loading time, which improves the overall user experience.

Encoding AVIF images

Let's go through some cross-platform tools for converting images into the AVIF format.

Squoosh

Google's Squoosh web app is a great playground and good enough for handling individual images. You can play around with compression settings and compare the output to other formats. The file-size limit is 4 MB.

Squoosh app screenshot

Squoosh CLI

Update: The Squoosh CLI is no longer maintained. The last version 0.7.3 is not compatible with Node 18+.

Squoosh is also available as a CLI tool, which is a great alternative for frequent usage and batch processing:

squoosh-cli --avif '{speed: 2}' cow.jpg

In this example, squoosh will create a cow.avif file. As of current version 0.7.3, the output file name cannot be changed.

A low speed parameter will make the conversion much slower, but the file size will be smaller. That's a trade-off I'm happy to make.

ImageMagick

ImageMagick is my usual choice as an all-around image processing CLI tool. Since version 7.0.25, it supports AVIF compression natively:

magick -quality 75 cow.jpg cow.avif

You can specify additional AVIF settings using the "-define" command-line option. For example, you can replace the generic quality parameter with a heic:speed option to get better results:

magick -define heic:speed=2 cow.jpg cow.avif

FFmpeg

FFmpeg is mainly a video/audio processing tool, but it can handle still images, too. AVIF is supported starting with version 5.1:

ffmpeg -i cow.jpg -c:v libaom-av1 -still-picture 1 cow.avif

FFmpeg can also generate animated AVIF files, which is a great alternative to GIFs:

ffmpeg -i video.mp4 animation.avif

AVIF converter

Last but not least, there is avif.io, another web-based AVIF converter. It supports bulk conversion, making it a good alternative for batch processing without installing a CLI tool. The website also contains useful articles and tutorials about the AVIF format.

Progressive enhancement

As of July 2022, the WebP global usage is ~97% and AVIF is ~72%. Fortunately, there are backwards-compatible features to provide a fallback for unsupported browsers.

HTML

In HTML, we can use the <picture> tag:

<picture>
  <source type="image/avif" srcset="cow.avif" />
  <source type="image/webp" srcset="cow.webp" />
  <img src="cow.jpg" srcset="cow.png" alt="Cow" />
</picture>

In this example, the browser will match the formats from top to bottom and use the first one that it supports. AVIF is listed as the first format, as it provides the best compression.

If the browser doesn't support <picture> at all (I'm looking at you, IE11), all the <source> entries will be ignored and the JPEG <img> picture will be used as fallback. This is a perfect example of progressive enhancement.

CSS

The image-set function provides a similar solution for CSS images:

.box {
  background-image: url("cow.jpg"); /* fallback */
  background-image: image-set(
    url("cow.avif") type("image/avif"),
    url("cow.jpg") type("image/jpeg")
  );
}

As of August 2022, only Firefox 89+ supports the type attribute. Unsupported browsers will ignore the second background-image definition and fall back to the JPEG image instead.

Debugging the picture element

In Chrome, you can simulate missing WebP and AVIF support:

Chrome rendering tab

But how can you tell, which of the referenced picture images your browser chose to display?

A browser-independent way is to select the img element in the DOM inspector and type the following into the console:

$0.currentSrc;

Viewing active image within a picture element

In Chrome DevTools, this information is also displayed when you hover the src or srcset value of your img element:

Chrome DevTools displaying the image currentSrc value

Firefox might provide something similar in the future.

The screenshots on this page include multiple image types, so try it out yourself. 🔎

Related posts

Web developer's guide to AVIF images