AVIF encoding gets cheaper and more practical
Image payloads remain one of the most common sources of performance problems on the web. Modern compression formats are the standard remedy, and AVIF — an image format based on the AV1 video codec and standardized by the Alliance for Open Media — has become an increasingly attractive option. AVIF consistently delivers file sizes more than 50% smaller than JPEG, with exact savings depending on content, encoding settings, and quality targets. The format also brings support for High Dynamic Range, Wide Color Gamut, film grain synthesis, and progressive decoding.
For a long time, the biggest obstacle to AVIF adoption was encoding cost. Recent improvements to the open source tooling have largely addressed that. Here’s what changed and how to put the format to work.
Where the open source ecosystem stands now
AVIF support has matured considerably since Chrome landed it in M85, particularly in the two libraries that matter most.
Libaom
Libaom is the open source AV1 encoder and decoder maintained by Alliance for Open Media members, and it powers many production services at Google and elsewhere. Between the 2.0.0 release (which coincided with Chrome’s initial AVIF support) and the recent 3.1.0 release, still image encoding received major optimizations:
- Multi-threading and tiled encoding optimizations.
- A 5x reduction in memory usage.
- A 6.5x reduction in CPU usage.
These changes drastically reduce the cost of encoding AVIF, particularly for the highest-priority images on a site. As hardware-accelerated AV1 encoding becomes more common on servers and cloud platforms, the cost will keep falling.
Libavif
Libavif is the reference AVIF implementation, used by Chrome for decoding, and it can also create AVIF images from uncompressed sources or transcode from formats like JPEG and PNG. Recent updates add support for a wider range of encoder settings, including advanced libaom options. The processing pipeline now benefits from libyuv-powered YUV-to-RGB conversion and premultiplied alpha support. Critically, libavif also supports the all-intra encoding mode introduced in libaom 3.1.0, which brings all of those encoding speedups to AVIF still images.
Trying AVIF without a build
Squoosh.app is the quickest way to experiment with AVIF. It runs a WebAssembly build of libavif in the browser and exposes most of the same features as the command line tools, making it easy to compare formats. A CLI version of Squoosh is also available for Node apps.
WebAssembly cannot yet access all CPU performance primitives, though, so for the fastest encoding you’ll want the native command line tool, avifenc.
Building avifenc from source
This tutorial walks through building avifenc statically linked against libaom. You’ll need Chrome 85 or later, cmake, git, ninja, plus development packages for zlib, libpng, and libjpeg. On Debian or Ubuntu:
sudo apt-get install zlib1g-dev sudo apt-get install libpng-dev sudo apt-get install libjpeg-dev
Getting the code and building libaom
Check out a release tag of libavif:
git clone -b v0.9.1 https://github.com/AOMediaCodec/libavif.git
Change into the libavif directory:
cd libavif
Many build configurations are possible; this one targets a static libaom. Move to the external dependencies directory:
cd ext
Fetch the libaom source and build it statically:
./aom.cmd
Return to the libavif directory:
cd ..
Compiling avifenc
Create a dedicated build directory:
mkdir build
Move into it, then generate the build files and compile:
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0 -DAVIF_CODEC_AOM=1 -DAVIF_LOCAL_AOM=1 -DAVIF_BUILD_APPS=1 ..
make
Encoding your first AVIF image
The avifenc command structure looks like:
./avifenc [options] input.file output.avif
The key parameter is --cq-level, which sets the quantize level from 0 to 63 to control color or alpha quality. A basic two-argument invocation specifying input and output files works, but a good starting point for a quality level of 18 is:
./avifenc happy_dog.jpg happy_dog.avif
./avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim happy_dog.jpg happy_dog.avif
Run ./avifenc with no arguments to see all available options.
Using multiple cores
The --jobs parameter controls how many threads avifenc uses. On an 8-core machine:
./avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim --jobs 8 happy_dog.jpg happy_dog.avif
That yields roughly a 5x speedup in encoding time.
AVIF and LCP optimization
Images are frequent candidates for Largest Contentful Paint (LCP). Smaller transfer sizes directly improve the resource load time, one of the four key phases to target for image-based LCP candidates.
An image CDN is the strongly recommended path for image optimization — it avoids maintaining encoder pipelines in your build process. For projects where a CDN isn’t feasible, these pointers for using avifenc are worth keeping in mind:
- Review the full set of encoder options. Experimenting with AVIF’s encoding features can yield additional savings while preserving visual quality.
- AVIF supports both lossy and lossless modes. JPEG-style photographs generally perform best with lossy encoding, while simple graphics or line art that normally ships as PNG will often do better lossless.
- If you use a bundler with imagemin community support, the
imagemin-avifpackage lets your build output AVIF variants without manual encoding steps.
These efforts may translate into measurable LCP improvements when the LCP candidate is an image. Further guidance is available in the general LCP optimization guide.
With libaom, libavif, and related open source tools, AVIF is now a practical choice for balancing image quality and performance. The format is young, and both encoder optimizations and tooling integrations are evolving quickly. For questions or feature requests, the av1-discuss mailing list, AOM GitHub community, and AVIF wiki are the active forums for discussion.



