作者:vivo 互联网前端团队- Liu Daqiang
本文分享 vivo 社区在 WebP 已全面落地的基础上,引入下一代图片格式 AVIF 的实践经验。通过 CDN 边缘缓存 + 服务端异步转码的方案,在保证画质的前提下,图片体积相比 WebP 进一步降低 20%+,有效提升了用户的浏览体验。
1分钟看图掌握核心要点👇
图 1 VS 图 2,您更倾向于哪张图来辅助理解全文呢?欢迎在评论区留言。
vivo 社区作为内容聚合平台,图片与视频流量占比较高。在弱网等复杂环境下,首屏图片加载缓慢会直接导致 LCP(最大内容绘制)、FCP(第一次内容绘制)等核心性能指标不佳,进而影响用户的浏览深度与留存。
尽管我们已经通过 WebP 格式将图片体积优化了约 50%,但对用户体验的追求是持续不断的。随着 AVIF 格式的成熟与浏览器支持率的提升,我们决定对其进行调研与落地,旨在 WebP 的基础上进行"二次瘦身"。
卓越的压缩效率:
AVIF 基于先进的 AV1 视频编码标准。在同等主观画质下,其体积相比 JPEG 可减小 60% 以上;即使在相同码率下,其 PSNR(峰值信噪比)和 SSIM(结构相似性)指标也优于 WebP,能保留更多图像细节。
强大的生态支持:
Chrome、Firefox、Edge 及 Safari 16+ 已全面支持,移动端覆盖率达 90% 以上。主流 CDN 与服务商(如 Cloudflare、阿里云)均已提供转码支持,开源工具链也趋于完善。
可行的收益目标:
我们设定的技术目标是,在 PSNR ≥ 35 dB 的前提下,AVIF 体积相比 WebP 能有 20% 以上的缩减。调研数据表明,这一目标具备可行性。
我们的核心设计原则是: 为支持 AVIF 的客户端提供最优体验,对不支持的客户端实现无缝降级,并确保服务端稳定性。
整体流程如下图所示:
方案核心点解析:
我们的 核心思路是:
在前端首先检测浏览器是否支持 AVIF 格式,如果支持,则在图片请求的 URL 中附加参数(或修改 URL 路径)以请求 AVIF 格式;否则回退至 WebP 格式。
我们使用 Image 对象进行异步检测,以判断浏览器是否支持 AVIF 解码。
/**
* 检测浏览器是否支持 AVIF 图片格式
* @returns {Promise<boolean>}
*/
async function checkAvifSupport(){
// 创建一个 Image 对象,并设置 src 为一个最小的、有效的 AVIF 图片数据
returnnew Promise((resolve) => {
const image = new Image();
image.onload = image.onerror = () => {
resolve(image.height === 2);
};
image.src =
"data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
});
}
// 由于检测是异步操作,我们通常会在应用初始化时执行一次检测,并将结果缓存起来以供后续使用。
let isAvifSupported = false;
(async () => {
isAvifSupported = await checkAvifSupport();
})();根据检测结果,动态组装请求图片的 URL。
/**
* 根据浏览器支持情况,生成最优格式的图片 URL
* @param {string} imageId 图片的唯一标识符
* @param {string} defaultFormat 默认格式,如 'webp'
* @returns {string}
*/
function getOptimizedImageUrl(imageId, defaultFormat = "webp"){
const format = isAvifSupported ? "avif" : defaultFormat;
return `https://cdn.example.com/images/${imageId}.${format}`;
}如果图片加载失败,无论是还未生成 avif 图片,还是其他原因导致的异常,都会自动降级到 WebP 格式。
<img :src="getOptimizedImageUrl(imageId)">
<script>
const img = document.querySelector('img');
// 设置降级逻辑
img.onerror = function() {
const currentSrc = this.src;
const baseUrl = currentSrc.substring(0, currentSrc.lastIndexOf('.'));
if (currentSrc.endsWith('.avif')) {
this.src = baseUrl + '.webp';
} elseif (currentSrc.endsWith('.webp')) {
this.src = baseUrl + '.jpg';
}
};
</script>我们采用客观数据与主观评测相结合的方式:
客观指标:体积压缩率、PSNR (≥35 dB 为目标)、SSIM(≥0.95 为目标)。
主观评测:团队内部对转换后的图片进行盲测,确保无肉眼可见的质量损失
实验条件:
以下为一期(CRF=32)与二期(CRF=35)调优后的部分数据对比:
表注:
下图为人物风景图片和海报类图片的渲染效果,这是我们使用到的主要图片类型,原图,WebP 图片,AVIF 图片放到一起比较基本看不出差别,海报类图片中文字清晰无损失。
▼【人物风景图】
▼【海报类图】
在加载速度方面,于同一设备及网络条件下,AVIF 图片的加载速度明显快于 WebP 要快(原图较大,考虑到带宽影响,验证视频未加载原图,左边为原图,中间为 WebP,右边为 AVIF)
通过线上 A/B 测试验证,采用 AVIF 格式后:
通过引入 AVIF 并采用稳健的降级方案,vivo 社区在未牺牲兼容性与用户体验的前提下, 显著降低了带宽成本,并提升了核心页面的加载性能,验证了 AVIF 在大型内容平台落地的价值。
1. PNG 转 AVIF 对比 Webp 似乎收益不明显?
2.转码速度与性能开销怎么样?
参考资料
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69912579/viewspace-3117230/ ,如需转载,请注明出处,否则将追究法律责任。