Ahammed Rashad

Why We Switched to AVIF

How we cut preview weight while keeping image quality, transparency, and the parts of our media pipeline we already trusted.

01 · JPEG and AVIF

The same frame, encoded twice

We started with the part users would actually see: one frame at the same dimensions, encoded both ways. Start with the same file-size budget to expose what each format preserves. Then switch to similar quality to compare the amount of data they need. Drag across the image and use the inspection tabs to look closer. Encoder settings are format-specific, not a shared quality scale.

Colour studio interior encoded as JPEGAVIF · 19.6 KBJPEG · 18.9 KB
JPEG18.9 KBencoder setting 5
AVIF19.6 KBencoder setting 26
Budget≈ 20 KBeach at 1440 × 810
02 · The encoding constraint

Keep the pipeline, change the encoder

Tessact already extracted frames with FFmpeg 4.4.2 and assembled PNG sprites with Pillow. It was predictable, but every additional preview increased storage and transfer.

Our first assumption was that the existing FFmpeg step could write AVIF too. It could not: Ubuntu 22.04 shipped us FFmpeg 4.4.2 without the encoder we needed.

Replacing FFmpeg would solve one codec problem while creating risk elsewhere. An external PPA added a dependency we did not control, static builds were harder to maintain, and a broader system upgrade was already conflicting with Python packages in the stack.

We kept FFmpeg doing what it already did well: capturing frames as PNG. A second, isolated step passed them to the libavif CLI and produced the AVIF thumbnails and sprite sheets. That kept the new encoding work separate from a frame-extraction path we already trusted in production.

03 · Alpha transparency

Transparency has to survive both themes

Motion graphics often arrive with an alpha channel. Switch the background and format to see why flattening them into JPEG was not acceptable.

LightDark
JPEG chart preview on dark interface
JPEGFlattened background · 10.0 KB
AVIF chart with transparency on dark interface
AVIFAlpha preserved · 4.9 KB

JPEG carries its flattened background into the interface. AVIF keeps the feathered edge transparent across both themes.

04 · Scrubbing previews

A sprite sheet becomes a timeline

These 24 frames were sampled across a three-minute video, converted to monochrome, given a fine layer of grain, and arranged into a 6 × 4 sheet. In production, Tessact packs more than 100 frames into a sheet that stays below 500 KB.

Drag to scrub00:00:00
24 monochrome frames with grain3.0 MB PNG102 KB AVIF
05 · Loading the library

Smaller previews change how the library feels

Load the same demo sheet into a grid of video previews. The time is a theoretical transfer at 10 Mbps; decoding and network latency vary.

AVIF≈ 0.08 sraw transfer at 10 Mbps

The result was practical: sharper thumbnails, working transparency, and a 102 KB demo sprite where PNG needed 3.0 MB. More of the library could arrive before the user noticed it loading.