Framer 如何实现 AVIF

阅读 0 分钟

分享

分享

2024年5月,我们推出了对AVIF格式的支持。Framer上的所有图片现在都以AVIF格式提供,使文件体积缩小约20%。然而,集成这种格式存在挑战,部分原因是将图像转换为AVIF的过程较慢。以下是我们的解决方案。

挑战:AVIF 编码速度慢

在 Framer,我们在第一次请求时优化每一张图片。优化后的图片随后被缓存到 CDN 上。

这是一种常见的方法,它运行良好,但也有一个缺点。因为第一次未缓存的请求必须转换和调整图片大小,所以它比后续请求花费的时间更长。对于 WebP 来说,“更长”是显而易见的但可以接受的:在我们的基础设施中,WebP 转换通常会增加 100-300 毫秒。然而,对于 AVIF,这会增加到 1-2 秒。

旁注:“1-2 秒?这还不够快吗?”——这很快,但只在计算机上下文之外。“研究表明,用户在仅仅 100 毫秒后就会觉得事情不是即时的。”

Framer 图片的缓存命中率约为 98%。如果我们忽略这个问题并切换到 AVIF,每第 50 张图片将需要几秒钟才能加载。我们认为这是不可接受的,因此 Framer 的Jacob提出,并且Piotr实现了一个巧妙的策略,避免了这种情况——`stale-while-revalidate` 头部。

解决方案:`Stale-While-Revalidate`

stale-while-revalidate是一种缓存设置。它是`Cache-Control`头部中的一个参数,它告诉 CDN 在图片过期后可以继续提供多长时间:

Cache-Control: max-age=3600, stale-while-revalidate=60
               文件可缓存多久
                             CDN max-age 过期后可继续提供
                               文件多久

以下是我们如何使用它来确保 AVIF 永远不会使图片响应变慢:

1. 首次请求:WebP

  • 在第一个请求中,我们将图片作为 WebP 提供,而不是 AVIF。

  • 我们还将`Cache-Control`头部设置为`max-age=0, stale-while-revalidate=31536000`

2. 立即过期

  • 由于`max-age`设置为 0,WebP 图片立即过期。这会促使 CDN 将第二个请求转发给我们。

3. 第二次请求:AVIF

  • 当第二个请求到达时,我们将图片作为 AVIF 提供。

    • 响应第二次请求可能需要几秒钟,因为 AVIF 转换很慢。但多亏了`stale-while-revalidate`,我们的 CDN (CloudFront) 会继续提供 WebP 图片,直到转换完成。

    • 我们通过`If-None-Match`头部识别第二次请求与第一次请求。只有第二次请求才有它。

  • 当 AVIF 图片准备好后,我们将其与`Cache-Control: max-age=31536000`一起返回。这允许 CDN 缓存并长期提供它。

这出乎意料地有效——最重要的是,它使我们能够保持基础设施的简单。如果不是这个技巧,我们将需要实现一个单独的队列系统来在后台转换图像。但是有了这个技巧,我们不需要——因此没有额外的复杂性,也没有额外的错误。

我们何时不使用 AVIF

AVIF 现在是大多数图片的默认格式。但仍有一些场景我们继续使用 WebP:

Create a free website with Framer, the website builder loved by startups, designers and agencies.