图片通常占据了网页上下载字节的大部分,通常也占据了大量的视觉空间。因此,优化图片通常可以极大地节省字节数并提升网站性能:浏览器需要下载的字节数越少,对客户端带宽的竞争就越少,浏览器下载并在屏幕上呈现有用内容的速度就越快。
图像优化既是一门艺术,也是一门科学:说它是一门艺术,是因为对于如何以最佳方式压缩单个图像,并没有明确的答案;而说它是一门科学,则是因为有许多成熟的技术和算法可以显著减小图像的大小。为找到图片的最佳设置,需要从许多维度进行仔细分析:格式功能、编码数据的内容、质量、像素尺寸等。
优化矢量图像
所有现代浏览器都支持可缩放矢量图形 (SVG),这是一种基于 XML 的二维图形图片格式。您可以直接将 SVG 标记嵌入网页中,或将其嵌入外部资源。 大多数基于矢量的绘图软件都可以创建 SVG 文件,或者您也可以直接在自己喜欢的文本编辑器中手动编写这些文件。
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 612 792" xml:space="preserve">
<g id="XMLID_1_">
<g>
<circle fill="red" stroke="black" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/>
</g>
</g>
</svg>
上面的示例渲染了下方带有黑色轮廓和红色背景的简单圆形,并且是从 Adobe Illustrator 导出的。
<?xml version="1.0" encode="utf-8"?>
您可以看出,它包含大量元数据,例如图层信息、注释和 XML 命名空间,在浏览器中渲染资源通常并不需要这些内容。因此,建议您使用 SVGO 等工具来缩小 SVG 文件。
举个有说服力的例子,SVGO 将 Illustrator 生成的上述 SVG 文件的大小减少了 58%,将其从 470 字节减少到 199 字节。
<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 792"><circle fill="red" stroke="#000" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/></svg>
由于 SVG 是一种基于 XML 的格式,因此您还可以应用 GZIP 压缩来减小其传输大小,请确保您的服务器配置为压缩 SVG 资源!
光栅图片就是单个“像素”的二维网格。例如,100x100 像素的图片是 10,000 像素的序列。相应地,每个像素存储“RGBA”值:(R) 红色通道、(G) 绿色通道、(B) 蓝色通道和 (A) alpha(透明度)通道。
在内部,浏览器会为每个通道分配 256 个值(阴影),相当于每个通道 8 位 (2 ^ 8 = 256),每个像素 4 个字节(4 个通道 x 8 位 = 32 位 = 4 个字节)。因此,如果我们知道网格的尺寸,就可以轻松计算出文件大小:
- 100x100 像素的图片由 10,000 像素组成
- 10,000 像素 x 4 个字节 = 40,000 个字节
- 40,000 字节 / 1024 = 39 KB
尺寸 | 像素 | 文件大小 |
---|---|---|
100 x 100 | 10000 | 39 KB |
200 x 200 | 40000 | 156 KB |
300 x 300 | 90,000 | 351 KB |
500 x 500 | 250000 | 977 KB |
800 x 800 | 64 万 | 2500 KB |
100x100 像素图片的文件大小为 39 KB 可能看起来不是什么大问题,但对于较大的图片,文件大小会迅速暴增,并会导致图片资源的下载速度缓慢且费用高昂。到目前为止,本博文仅重点介绍“未压缩”图片格式。 幸运的是,你可以采取许多措施来减小图片文件大小。
一种简单的策略是将图像的“位深”从每个通道 8 位减少为更小的调色板:每个通道 8 位为每个通道提供 256 个值,共计提供 16,777,216 (256 ^ 3) 种颜色。如果将调色板减少到 256 色,会发生什么情况? 那么 RGB 通道总共仅需 8 位,每个像素可立即节省两个字节,与原来的每像素 4 个字节格式相比,这在压缩方面节省了 50%!
![压缩伪影](https://web.developers.google.cn/static/articles/compress-images/image/compression-artifacts-0440f2089a09b.png?authuser=6&hl=sr)
具有逐步颜色过渡的复杂场景(例如渐变或天空)需要较大的调色板,以避免 5 位资源中的像素化天空等视觉伪影。另一方面,如果图片只使用几种颜色,那么较大的调色板只会浪费宝贵的位数!
接下来,在优化完各个像素中存储的数据后,您可以更聪明地观察一下附近的像素:结果发现,许多图片(尤其是照片)都有许多相邻的像素具有相似的颜色,例如天空、重复的纹理等。利用这些信息,压缩器可以应用增量编码,这样,您就可以存储相邻像素之间的差异,而不是存储每个像素的单独值:如果相邻像素相同,则增量为“零”,您只需存储一个位! 但为什么到此就止步了...
人眼对不同颜色的敏感度有所不同:为了解决这个问题,您可以通过减小或增加这些颜色的调色板来优化颜色编码。“附近”像素形成二维网格。这意味着每个像素都有多个相邻像素:您可以利用这一点进一步改进增量编码。您可以查看较大的邻近像素块,并使用不同设置对不同的块进行编码,而不是仅查看每个像素的直接相邻块。
如您所见,图片优化很快就会变得复杂(或很有趣,具体取决于您的观点),并且是学术和商业研究的一个活跃领域。由于图片占用了大量字节,因此开发更好的图片压缩技术具有很大的价值! 如果您想了解详情,请访问维基百科页面,或查看 WebP 压缩技术白皮书以获取实操示例。
再次强调,这些都非常棒,但又具有学术意义:它如何帮助您优化网站上的图片? 了解问题的形状非常重要:RGBA 像素、位深和各种优化方法。在您深入讨论各种光栅图像格式之前,理解和牢记所有这些概念都至关重要。
无损图片压缩与有损图片压缩
对于某些类型的数据(例如页面的源代码或可执行文件),请务必确保压缩程序不会更改或丢失任何原始信息:单点缺失或错误的数据就可能完全改变文件内容的含义,更糟的情况下甚至会完全破坏文件。 对于一些其他类型的数据(例如图像、音频和视频),提供原始数据的“近似”表示可能完全可以接受。
事实上,由于眼睛的运作方式,我们通常可以通过舍弃每个像素的一些信息来减小图像的文件大小。例如,人眼对不同颜色的敏感度不同,这意味着我们可以用更少的位数对某些颜色进行编码。因此,典型的图像优化管道包含两个高级步骤:
第一步是可选的,确切的算法取决于特定的图片格式,但请务必注意,任何图片都可通过有损压缩步骤来减小其大小。事实上,各种图片格式(例如 GIF、PNG、JPEG 及其他格式)之间的区别在于它们在应用有损和无损步骤时使用的特定算法的组合。
那么,有损和无损优化的“最佳”配置是什么? 答案取决于图片内容和您自己的标准,例如文件大小与有损压缩带来的伪影之间的权衡:在某些情况下,您可能需要跳过有损优化,以完整保真度传达复杂的细节。在其他情况下,您可以应用积极的有损优化来减小图片资源的文件大小。这就需要您自行判断和判断背景,因为没有统一的设置。
举一个实例,在使用有损格式(如 JPEG)时,压缩程序通常会提供可自定义的“质量”设置(例如,Adobe Photoshop 中的“Save for Web”功能提供的质量滑块),该设置通常为 1 到 100 之间的数字,用于控制特定有损和无损算法集合的内部工作原理。为了获得最佳效果,请对图片进行各种质量设置进行实验,不要害怕调低质量 - 视觉效果通常非常好,而且文件大小的缩减幅度可能相当大。
图片压缩对核心网页指标的影响
由于图片通常是进行 Largest Contentful Paint 的候选项,因此缩短图片的资源加载时长有助于在实验和现场中实现更好的 LCP。
对光栅图片格式调整压缩设置时,请务必尝试 WebP 和 AVIF 格式,看看与旧格式相比,能否以较小的占用空间来传送相同的图片。
但要注意不要对光栅图片造成过度压缩。一个很好的解决方案是使用图片优化 CDN 找到最适合您的压缩设置,但另一种方法是使用 Butteraugli 等工具来估算视觉差异,这样您就不会过度频繁地对图片进行编码,而对图片质量造成负面影响。
图片优化核对清单
在优化图片时,请注意以下提示和技巧:
- 首选矢量格式:矢量图像与分辨率和缩放无关,因此非常适合多设备和高分辨率的情况。
- 缩小和压缩 SVG 资源:大多数绘图应用生成的 XML 标记通常包含可以移除的不必要的元数据;确保您的服务器配置为对 SVG 资源应用 GZIP 压缩。
- 首选 WebP 或 AVIF 而非较旧的光栅格式:WebP 和 AVIF 图片通常比旧图片格式小得多。
- 选择最佳的光栅图片格式:确定您的功能要求并选择适合每个特定资源的光栅图片格式。
- 尝试针对光栅格式的最优质量设置:不要害怕调低“质量”设置,结果通常非常好,并且能够显著减少字节数。
- 移除不必要的图片元数据:许多光栅图片都包含关于资源的不必要的元数据,例如地理位置信息、相机信息等。请使用适当的工具删除这些数据。
- 提供缩放后的图片:调整图片大小,并确保“显示”尺寸尽可能接近图片的“自然”尺寸。 尤其要密切注意大图片,因为在调整尺寸时,它们占用的开销最大!
- 自动化、自动化、自动化:投资购置自动化工具和基础架构,以确保您的所有图片资源始终得到优化。