前端优化指南:我们该怎么去压缩图像?

4,527 阅读3分钟

在网站性能优化中,图像的影响比其他大部分内容都要严重。

本文我们来聊聊如何在前端工程化中优化图像。

原理

图像是由很多个像素点组成的,在电脑上以电脑方阵的形式表示。

也就是每个像素点对应一个 rgb 值。只有采取这种做法的图片格式才是真正未被压缩的格式,比如 bmp,全称 bitmap。

但是这种格式的图片体积过大,加载速度慢,已经逐渐被淘汰了。

如今主流的图片格式都是压缩过的图片格式,主流的比如 png 和 jpeg。

jpeg 压缩的思路是把一张图片切割成多个小格子,把每个格子中相同的 rgb 值转换为 YUV(亮度、色调、饱和度),再进行量化就可以降低图片的整体体积。

png 压缩的思路是复用相同的 rgb 值来降低体积。

但是在实际中具体的图像压缩过程非常复杂,本文不展开讲,我们主要来看看目前业界主流的做法。

主流打包器的做法

图像压缩时通常会有一个 quality 参数,表示质量,最低为 1,最高为 100。质量越高体积越大,质量越低体积越小。

通常建议为 75-80,不建议小于 60。

webpack 的压缩主要是依靠 image-minimizer-webpack-plugin 这个插件,它的底层依赖了 imagemin 这个库。

rollup由于更偏向于 JavaScript 库的打包,所以它会利用 @rollup/plugin-image 将图片打包成 base64 编码的格式,底层使用了 mini-svg-data-uri

next/image 采用 sharp 来压缩图像,默认的质量是 75。

parcel 也是采用了 sharp 来压缩图像。

sharp vs imagemin vs jimp

我通过 npmtrends 对比了几个图像压缩库的使用趋势。

并且从其中又挑选了最主流的三个图像压缩库做对比,它们分别是 sharp、imagemin 和 jimp。

为了直观的对比它们的差异,我做了一个在线图像压缩的网站。

www.webbuild.me/compress-im…

这个网站和其他图片压缩网站不同的地方是,它除了具备基本的 jpg、png 压缩、批量压缩、转换 webp、选择压缩质量以外,还可以选择不同的压缩器。

我选择了三张图片进行压缩对比:

格式质量压缩前压缩后转换 webp 后
sharpjpeg75266kb138kb94kb
imageminjpeg75266kb114kb94kb
jimpjpeg75266kb174kb不支持
sharpjpeg75557kb516kb239kb
imageminjpeg75557kb436kb239kb
jimpjpeg75557kb682kb不支持
sharppng7566kb23kb9kb
imageminpng7566kb19kb9kb
jimppng7566kb88kb不支持

其实很好看出,imagemin 在 jpeg 和 png 的优化能力上最强,webp 模式下 sharp 和 imagemin 没有区别。jimp 会莫名其妙的负压缩。

jimp 的优势是不依赖 runtime 平台,它是零依赖的纯 JavaScript 实现。

sharp 和 imagemin 都依赖特定平台,但是它们在压缩能力上更加优秀。

不过 sharp 更加成熟和稳定,没有特殊要求,还是建议首选 sharp。

总结

作为打包网站类应用来讲的话,主流的方案很简单:

  • 体积小的图片(通常指小于 10kb)转换为 base64。
  • 体积大的图片(通常值大于 10kb)使用 webp 格式。
  • 体积大但不是特别重要的图片,建议按照 75 的质量进行压缩。