Framer Partner Logo
Framer Partner Logo

How Framer Integrated AVIF for Faster, Smaller, and Sharper Images

In May 2024, Framer shipped AVIF support. All images on Framer are now served as AVIF, which makes them ~20% smaller. However, integrating this format was challenging, partly because converting images to AVIF is slow. Here’s how we solved this.

avif image format Framer
avif image format Framer
avif image format Framer

Challenge: AVIF Encoding Is Slow

At Framer, we optimize every image on the first request. The optimized image is then cached on a CDN.

This is a common approach, and it works well, but it comes with a drawback. Because the first uncached request has to convert and resize the image, it takes longer than subsequent ones. With WebP, “longer” is noticeable but acceptable: in our infrastructure, WebP conversion typically adds 100-300 milliseconds. However, with AVIF, this grows to 1-2 seconds.

Sidenote: “1-2 seconds? Isn’t that still fast?” — It’s fast, but only outside computer contexts. Research shows that users start feeling things aren’t instant after just 100 milliseconds.

Framer’s cache hit for images is ~98%. If we ignored this issue and switched to AVIF, every 50th image would take several seconds to load. We felt this was unacceptable, so Framer’s Jacob came up with, and Piotr shipped a clever strategy that avoided that – the stale-while-revalidate header.

Solution: Stale-While-Revalidate

stale-while-revalidate is a caching setting. It’s a parameter in the Cache-Control header, and it tells CDNs how long they can keep serving the image after it expires:

Cache-Control: max-age=3600, stale-while-revalidate=60 ↑ how long a file can be cached for ↑ how long a CDN can keep serving the file after max-age expires

Here’s how we used it to make sure AVIF never makes image responses slow:

1. First Request: WebP

  • On the first request, we serve the image as WebP, not as AVIF.

  • We also set the Cache-Control header to max-age=0, stale-while-revalidate=31536000

2. Immediate Expiry

  • Because max-age is set to 0, the WebP image expires immediately. This prompts the CDN to forward the second request to us.

3. Second Request: AVIF

  • When the second request arrives, we serve the image as AVIF.

    • Responding to the second request can take several seconds because AVIF conversion is slow. But thanks to stale-while-revalidate, our CDN (CloudFront) keeps serving the WebP image until the conversion is complete.

    • We recognize the second request from the first by the If-None-Match header. Only the second request has it.

  • When the AVIF image is ready, we return it with Cache-Control: max-age=31536000. This allows the CDN to cache and serve it for a long time.

This works surprisingly well – and, best of all, allows us to keep our infrastructure simple. If not for this trick, we’d need to implement a separate queueing system for converting images in the background. But with this trick, we don’t need to – so there’s no extra complexity and no extra bugs.

When We Don’t Use AVIF

AVIF is now the default format for most images. But there are still a few scenarios where we continue to use WebP:

revanth at spiti valley

About me

Hey, I'm Revanth
Web & Application designer.

With over 6 years into Experience design, I specialize in crafting intuitive web, mobile and application designs. As a freelancer and Framer expert, I'm here to bring your ideas to life.

I believe every business and entrepreneur deserves a seamless digital experience that effectively communicates their vision and value.

The challenge has always been that crafting intuitive, high-quality web and product designs can be complex, time-consuming, or out of reach for many.