图片资源,在我们的业务中可谓是占据了非常大头的一环,尤其是其对带宽的消耗是十分巨大的。

对图片的性能优化及体验优化在今天就显得尤为重要。本文,就将从各个方面阐述,在各种新特性满头飞的今天,我们可以如何尽可能的对我们的图片资源,进行性能优化及体验优化。

图片类型的选取及 Picture 标签的使用

首先,从图片的类型上而言,除了常见的 PNG-8/PNG-24,JPEG,GIF 之外,我们更多的关注另外几个较新的图片格式:

首先,通过一张表格,快速过一下这几个图片,我们将从图片类型、透明通道、动画、编解码性能、压缩算法、颜色支持、内存占用、兼容性方面,对比它们:

图片类型 Alpha 通道 动画 编解码性能 压缩算法 颜色支持 内存占用 兼容性
GIF 支持 支持 较高 无损压缩 索引色(256) 基本一致 ALL
PNG-8/PNG-24 支持 不支持 较高 无损压缩 索引色(256)\直接色 基本一致 ALL
JPEG 不支持 不支持 较高 有损压缩 直接色 基本一致 ALL
WebP 支持 支持 编解码性能差(低配设备更为显著) 有损压缩\无损压缩 直接色 基本一致 高版本 Chrome\Opera\Android
JPEG XL 支持 支持 渐进式解码 有损压缩\无损压缩 直接色 基本一致 部分高版本 Chrome\Opera\Firefox\Edge
AVIF 支持 支持 编解码性能一般 有损压缩\无损压缩 直接色 基本一致 高版本 Chrome\Opera\Android\Edge

首先,了解了解上述的一些参数含义:

当然,需要指出的是,Alpha 没有透明度的意思,不代表透明度。opacity 和 transparency 才和透明度有关,前者是不透明度,后者是透明度。比如 css 中的「opacity: 0.5」就是设定元素有 50% 的不透明度。后来 Alvy Ray Smith 提出每个像素再增加一个 Alpha 通道,取值为0到1,用来储存这个像素是否对图片有「贡献」,0代表透明、1代表不透明。也就是说,「Alpha 通道」储存一个值,其外在表现是「透明度」,Alpha 和透明度没啥关系

有损压缩算法是一种数据压缩方法,经过此方法压缩、解压的数据会与原始数据不同但是非常接近。原理是借由将次要的信息数据舍弃,牺牲一些质量来减少数据量、提高压缩比

无损压缩指数据经过压缩后,信息不受损失,还能完全恢复到压缩前的原样。无损压缩通常用于严格要求“经过压缩、解压缩的数据必须与原始数据一致”的场合。

索引颜色是一种以有限的方式管理数字图像颜色的技术,以节省计算机内存和文件存储,同时加速显示刷新和文件传输。即用一个数字来代表(索引)一种颜色,在存储图片的时候,存储一个数字的组合,同时存储数字到图片颜色的映射。这种方式只能存储有限种颜色。索引色常见有1位(即黑白),8位(即灰阶/256色),16位(即高彩),24位(即真彩),30/36/48位(即全彩)。

直接色使用四个数字来代表一种颜色,这四个数字分别代表这个颜色中红色、绿色、蓝色以及透明度(即 RGBA)。现在流行的显示设备可以在这四个维度分别支持256种变化,所以直接色可以表示2的32次方种颜色。

WebP vs JPEG XL vs AVIF: JPEG 替代之战

因为传统的 PNG-8/PNG-24,JPEG,GIF 各自或多或少都存在一些问题,近些年来它们的替代方案之争也愈演愈烈,核心领跑者可能是 WebPJPEG XLAVIF

再简单了解了解它们:

WebP

WebP 最初由 Google 在 2010 年 9 月发布,其特性总结如下:

  1. 可以同时提供无损/有损压缩(像 JPEG 一样)和支持透明度(像 PNG 一样)的图片文件格式
  2. 支持动画效果(像 GIF 一样)
  3. WebP 主要优势在于有损编码,其无损编码的性能和压缩比表现一般
  4. WebP 的缺点在于其编解码性能不是特别理想
  5. 在兼容性方面,除了 IE,基本已经得到了全系列浏览器支持

对于复杂的图像(比如照片)来说,WebP 无损编码表现并不好,但有损编码表现却非常棒。相近质量的图片解码速度 WebP 相距 JPEG 也已经相差不大了,而文件压缩比却能提升不少。

下图是我之前还在 TX 的时候做的一个测试对比:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

加载同样张数的 JPEG 与 WebP 的耗时对比:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

对于 WebP 图片格式,简单做个总结:

  1. 目前 WebP 与 JPEG 相比较,据资料考证,编码速度慢 10 倍,解码速度慢 1.5 倍
  2. WebP 虽然会增加额外的解码时间,但由于大幅减少了文件体积,缩短了加载的时间,大页面图片量较多的场景下,页面的渲染速度是有较大加快的
  3. 目前而言,是 WebP、JPEG XL、AVIF 三者中兼容性最好的

截止至(2023-02-05)的兼容性图:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

JPEG XL

JPEG XL 由联合图像专家组(开发原始 JPEG 标准的同一组织)于 2021 年发布,旨在成为传统 JPEG 的长期替代品。作为一种免版税的开源标准,JPEG XL 的创建者希望其格式的开放性能够吸引网络开发人员采用该标准,该格式的扩展名为 .jxl,JXL 核心比特流于 2021 年 1 月冻结,文件格式于 2021 年 4 月定稿。:

JPEG XL 中的 X 指 2000 年以来的多个 JPEG 标准的名称:JPEG XT、JPEG XR、JPEG XS,而 L 表示 'long-term',表示“长期”。创建这种格式是为替换旧的JPEG文件格式,并使用足够长的时间。

其主要特点有:

看看同一张图片,相同质量下的大小表现:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

数据来源:技术周刊 2021-04-15:2021最值得期待的新技术 JPEG XL

JPEG XL 是目前而言,最有可能全面替代传统图片格式(Gif、PNG、JPEG)的下一代标准,当然,在今天,需要看看其兼容性:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

好吧,目前的兼容有点离谱。Chrome 从 91 版本开始已经实验室性质支持了 .jxl 格式的图片,需要通过 --enable-features=JXL 配置开启,遗憾的是,从 Chrome 110 开始,Chrome 又不再支持 JPEG XL 。

有趣的是,Chrome 从 110 版本开始中弃用了对 JPEG-XL 的支持,谷歌的回答是,人们对 JPEG-XL 没有足够的兴趣,并且与现有格式相比也没有足够的优势。谷歌之前一直对 JPEG 的支持都是实验性的性质的,他们认为 JPEG XL 缺乏生态系统支持,并且该格式没有足够多的好处(相对 WebP 和 AVIF)。也就是说,目前而言,Chrome 对 WebP 和 AVIF 等替代格式更感兴趣。

AVIF

最后,我们再来看看 AVIF 格式图片。

AVIF 是由开放媒体联盟 (AOM) 开发并于 2019 年发布的另一种最新图像格式。该格式基于 AV1 视频编解码器,源自视频帧。其特点如下:

看看 CaniUse 的数据:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

下图是 WebP vs JPEG XL vs AVIF 三者在图片解码上的性能表现:

现代图片性能优化及体验优化指南 - 图片类型及 Picture 标签的使用

图片来源于:Encode.su -- JPEG XL vs. AVIF

从图中可以看到,对于解码性能的对比,结果居然是 WebP > AVIF > JPEG XL 。JPEG XL 的编解码性能并没有其描述的那么强大。

图片格式总结

总结一下,WebP、AVIF 和 JPEG XL 都是浏览器不广泛支持的新型图像格式。虽然 WebP、AVIF 已经存在很长时间,但到今天,影响它们大规模使用的依旧是兼容问题。它们各自有各自的特点与优势,谁能胜出仍未知晓。

虽然 AVIF、JPEG XL 等新型图片格式未得到任何浏览器的完全支持,但是在新版本的 Chrome、Firefox 和 Edge Chromium,可以使用配置标志启用对应图像格式,配合 HTML 的 Picture 标签,我们还是可以一定程度上对我们的图片进行格式选择上的优化的。

这,就可以引出我们要说的第二部分 -- HTML Picture 标签的使用。

Picture 元素的使用

HTML5 规范新增了 Picture Element。那么 <picture> 元素的作用是什么呢?

<picture> 元素通过包含零或多个 <source> 元素和一个 <img> 元素来为不同的显示/设备场景提供图像版本。浏览器会选择最匹配的子 <source> 元素,如果没有匹配的,就选择 <img> 元素的 src 属性中的 URL。然后,所选图像呈现在 <img> 元素占据的空间中。

什么意思呢?怎么使用 <picture> 元素呢?

假设,没有 <picture> ,只有 <img> 元素,我们想尽可能在支持一些现代图片格式的浏览器上使用类似于上述我们提到的 WebP、AVIF 和 JPEG XL 等图片格式,而不支持的浏览器回退使用常规的 JPEG、PNG 等。没错,就是一种渐进增强的思想,该怎么办呢?

只能是 JavaScript 去写对应的逻辑,通过 JS 脚本进行特性查询,动态赋值给 <img> 的 src。

而有了 <picture> 后,浏览器将原生支持上述的一些列操作,我们来看看对应的语法:

<picture>
  <!-- 可能是一些对兼容性有要求的,但是性能表现更好的现代图片格式-->
  <source src="" type="image/avif">
  <source src="" type="image/webp">
   <!-- 最终的兜底方案-->
  <img src="" type="image/jpeg">
</picture> 

上述代码的含义是:

这意味着现在我们可以在不牺牲向后兼容性的情况下开始使用新的图像格式。

简而言之,<picture> 元素的作用:

  1. 通过 <source> 给出一系列对兼容性有所要求的现代图片格式选项
  2. 通过 <img> 给出兜底的高兼容性图片格式选项
  3. 浏览器通过对给出的图片格式做特性检测,要决定加载哪个 URL,user agent 检查每个 <source> 的 srcset、media 和 type 属性,来选择最匹配页面当前布局、显示设备特征等的兼容图像。
  4. 最终,所选图像呈现在 <img> 元素占据的空间中

总结

总结一下,本文对常见的图片格式以及最新的几种未被大规模兼容的图片格式进行的对比,它们分别是:

其后,着重介绍了 3 种现代图片格式:WebP、JPEG XL、AVIF。相对于 JPEG 等传统格式,它们在色彩表现、动画支持、是否支持无损有损压缩、压损比率、编解码性能上有着更进一步的提升,正在成为下一阶段 Web 图像的标准。

最后,介绍了 <picture> 元素,借助它,我们能更好的实现图片的渐进增强。

当然,本文只是现代图片性能优化及体验优化指南的第一篇,后续将给大家带来图片在:

等相关知识的介绍,感兴趣的可以提前关注。

最后

OK,本文到此结束,希望本文对你有所帮助 ?

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

发表回复