我们经常撰写关于图片导致网站臃肿的文章,并且像 Lighthouse 这样的工具会在图片加载对用户体验产生负面影响时突出显示,例如增加加载时间,或占用更重要资源的带宽。一种解决此问题的方法是使用现代压缩技术来减小图片的文件大小,而 Web 开发人员的新选择是 AVIF 图片格式。这篇博文讨论了 AVIF 开源工具的最新更新,介绍了 libaom 和 libavif 编码库,并包含一个使用这些库高效编码 AVIF 图片的教程。
AVIF 是一种基于 AV1 视频编解码器的图片格式,由开放媒体联盟 (Alliance for Open Media) 标准化。AVIF 比 JPEG 和 WebP 等其他图片格式提供显著的压缩增益。虽然确切的节省量将取决于内容、编码设置和质量目标,但我们和其他人已经看到比 JPEG 节省超过 50%。
此外,AVIF 还增加了对新图片功能(例如 高动态范围和广色域、胶片颗粒合成和渐进式解码)的编解码器和容器支持。
最新动态
自 Chrome M85 推出 AVIF 支持以来,开源生态系统中对 AVIF 的支持在许多方面都得到了改进。
Libaom
Libaom 是由开放媒体联盟中的公司维护的开源 AV1 编码器和解码器,并在 Google 和其他成员公司的许多生产服务中使用。在 libaom 2.0.0 版本(大约在 Chrome 添加 AVIF 支持的同一时间)和最近的 3.1.0 版本之间,代码库中添加了重要的静态图片编码优化。这些优化包括:
- 针对多线程和分块编码的优化。
- 内存使用量减少 5 倍。
- CPU 使用率降低 6.5 倍,如下表所示。

这些更改大大降低了 AVIF 编码的成本,尤其是网站上最频繁加载或优先级最高的图片。随着 AV1 的硬件加速编码在服务器和云服务上变得越来越普及,创建 AVIF 图片的成本将继续下降。
Libavif
Libavif 是 AVIF 的参考实现,是一个开源 AVIF 混合器和解析器,Chrome 使用它来解码 AVIF 图片。它还可以与 libaom 一起使用,从您现有的未压缩图片创建 AVIF 图片,或从现有的 Web 图片(JPEG、PNG 等)进行转码。
Libavif 最近添加了对更广泛的编码器设置的支持,包括与更高级的 libaom 编码器设置的集成。处理管道中的优化(例如使用 libyuv 的快速 YUV 到 RGB 转换和预乘 Alpha 支持)进一步加快了解码过程。最后,libaom 3.1.0 中新添加的全帧内编码模式的支持带来了上述所有 libaom 改进。
使用 avifenc 编码 AVIF 图片
快速试用 AVIF 的一种方法是 Squoosh.app。Squoosh 运行 WebAssembly 版本的 libavif,并公开了与命令行工具相同的许多功能。这是一种比较 AVIF 与新旧其他格式的简便方法。还有一个针对 Node 应用的 Squoosh CLI 版本。
但是,WebAssembly 尚无法访问 CPU 的所有性能原语,因此,如果您想以最快的速度运行 libavif,我们建议使用命令行编码器 avifenc。
为了解如何编码 AVIF 图片,我们将提供一个教程,使用与上述示例中相同的源图片。首先,您需要:
您还需要安装 zlib、libpng 和 libjpeg 的开发包。Debian 和 Ubuntu Linux 发行版的命令如下:
sudo apt-get install zlib1g-dev
sudo apt-get install libpng-dev
sudo apt-get install libjpeg-dev
构建命令行编码器 avifenc
1. 获取代码
检出 libavif 的发布标签。
git clone -b v0.9.1 https://github.com/AOMediaCodec/libavif.git
2. 更改目录到 libavif
cd libavif
有许多不同的方法可以配置 avifenc 和 libavif 以进行构建。您可以在 libavif 中找到更多信息。我们将构建 avifenc,使其静态链接到 AV1 编码器和解码器库 libaom。
3. 获取并构建 libaom
更改到 libavif 外部依赖项目录。
cd ext
下一个命令将拉取 libaom 源代码并静态构建 libaom。
./aom.cmd
更改目录到 libavif。
cd ..
4. 构建命令行编码工具 avifenc
为 avifenc 创建一个构建目录是个好主意。
mkdir build
更改到构建目录。
cd build
为 avifenc 创建构建文件。
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0 -DAVIF_CODEC_AOM=1 -DAVIF_LOCAL_AOM=1 -DAVIF_BUILD_APPS=1 ..
构建 avifenc。
make
您已成功构建 avifenc!
了解 avifenc 命令行参数
avifenc 使用以下命令行结构:
./avifenc [options] input.file output.avif
本教程中使用的 avifenc 基本参数如下:
avifenc | |
---|---|
--min 0 | 将颜色的最小量化器设置为 0 |
--max 63 | 将颜色的最大量化器设置为 63 |
--minalpha 0 | 将 Alpha 通道的最小量化器设置为 0 |
--maxalpha 63 | 将 Alpha 通道的最大量化器设置为 63 |
-a end-usage=q | 将速率控制模式设置为恒定质量 (Q) 模式 |
-a cq-level=Q | 将颜色和 Alpha 通道的量化级别都设置为 Q |
-a color:cq-level=Q | 将颜色的量化级别设置为 Q |
-a alpha:cq-level=Q | 将 Alpha 通道的量化级别设置为 Q |
-a tune=ssim | 调整为 SSIM(默认调整为 PSNR) |
--jobs J | 使用 J 个工作线程(默认值:1) |
--speed S | 设置编码器速度,范围为 0-10(最慢-最快。默认值:6) |
cq-level 选项设置量化级别 (0-63) 以控制颜色或 Alpha 通道的质量。
使用默认设置创建 AVIF 图片
运行 avifenc 最基本的参数是设置输入和输出文件。
./avifenc happy_dog.jpg happy_dog.avif
我们建议使用以下命令行来编码图片,例如量化级别为 18:
./avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim happy_dog.jpg happy_dog.avif
Avifenc 有许多选项会影响质量和速度。如果您想查看这些选项并了解更多信息,只需运行 ./avifenc
您现在拥有了自己的 AVIF 图片!
加速编码器
根据您的计算机上的核心数,可能需要更改的一个参数是 --jobs
参数。此参数设置 avifenc 将用于创建 AVIF 图片的线程数。尝试在命令行中运行此命令。
./avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim --jobs 8 happy_dog.jpg happy_dog.avif
这告诉 avifenc 在创建 AVIF 图片时使用 8 个线程,这会将 AVIF 编码速度大约提高 5 倍。
对最大内容渲染 (LCP) 的影响
图片是最大内容渲染 (LCP) 指标的常见候选对象。改进 LCP 图片加载速度的一个常见建议是确保图片已优化。通过减小资源的传输大小,您可以提高其资源加载时间,这是处理作为图片的 LCP 候选对象时要关注的四个关键阶段之一。
在优化图片时,强烈建议使用图片 CDN,因为它比在网站的构建过程中设置图片优化管道或手动使用编码器二进制文件来手动优化图片要省力得多。但是,对于某些项目来说,图片 CDN 的成本可能过高。如果您的项目属于这种情况,请在使用 avifenc 编码器进行优化时考虑以下事项:
- 熟悉编码器提供的选项。通过试验 AVIF 的一些可用编码功能,您可能会发现额外的节省,同时仍保持足够的图片质量。
- AVIF 提供有损和无损编码。根据图片的内容,一种类型的编码可能比另一种性能更好。例如,通常以 JPEG 格式提供的照片可能最适合有损编码,而无损编码可能最适合包含通常以 PNG 格式提供的简单细节或线条艺术的图片。
- 如果使用具有 imagemin 社区支持的打包器,请考虑使用 imagemin-avif 包,以使您的打包器能够输出 AVIF 图片变体。
通过试验 AVIF,在 LCP 候选对象是图片的情况下,您可能会意识到网站的 LCP 时间有所改进。有关优化 LCP 的更多信息,请阅读有关优化 LCP 的指南。
结论
使用 libaom、libavif 和其他开源工具,您可以为您的网站使用 AVIF 获得最佳的图片质量和性能。该格式仍然相对较新,并且优化和工具集成正在积极开发中。如果您有任何问题、意见或功能请求,请通过 av1-discuss 邮件列表、AOM GitHub 社区和 AVIF wiki 联系我们。