Bulandent / blog

高级前端进阶博客,记录个人前端成长之路。包括但不限制于:es6、node、vue、小程序、浏览器、网络、设计模式、算法和数据结构、web安全、性能优化、工程化等。
80 stars 8 forks source link

为你的网站加上 WebP 格式的图片吧 #24

Open Bulandent opened 3 years ago

Bulandent commented 3 years ago

为你的网站加上 WebP 格式的图片吧

之前写了一篇文章:jpg、gif、png和svg用于web上,我们该如何选择最合适的图像格式,介绍了这几种图片格式的特点,以及如何为网站选择合适的图片,然后评论区有位大佬让我补充下 WebP 格式,于是乎它来了。

什么是 WebP 格式

WebP 是一种现代图像格式,可为 Web 上的图像提供出色的无损和有损压缩。 使用 WebP,网站管理员和 Web 开发人员可以创建更小,更丰富的图像,从而使 Web 更快。

与 PNG 相比,WebP 无损图像的尺寸要小 26%。 在同等的 SSIM 质量指数下,WebP 有损图像比同类 JPEG 图像小 25-34%。

无损 WebP 支持透明性(也称为 Alpha 通道),而仅增加了 22% 的字节数。 对于可以接受有损 RGB 压缩的情况,有损 WebP 还支持透明性,与 PNG 相比,文件大小通常小 3 倍。

上面这 3 段话来源于 https://developers.google.com/speed/webp

为什么你需要这个格式

因为 WebP 图像比 JPEG 和 PNG 图像小-通常文件大小减少 25-35%。这样可以减小页面大小并提高性能。举 2 个例子:

WebP 是 JPEG,PNG 和GIF 图像的理想替代品。 另外,WebP 提供无损压缩和有损压缩。 在无损压缩中,不会丢失任何数据。 有损压缩会减小文件大小,但会以降低图像质量为代价。

如何将图片转成 WebP 格式

通常,开发者会用如下两种方式来将图片转成 WebP 格式:

如果你的项目比较简单或者你仅需要将图片转化一次,那么 cwebp 命令行工具是一个很好的选择;而如果你使用构建工具比如 WebpackGulp 等去构建你的项目的时候,那么将图片转 WebP 使用 Imagemin WebP 插件就是你最好的选择了。

当你需要把图片转成 WebP 格式的时候,你可以设置很多的参数,但是你最需要关心的就仅仅只是压缩质量,你可以指定一个压缩的质量等级,它的范围是从 0 ~ 100,0 表示质量最差,100 是最好。那么该把它设置成多少才最合适呢?这就需要你好好的花费一翻功夫去实践到底哪个质量等级是既兼顾了呈现质量又不会使得文件太大呢?

使用 cwebp 转换图片

使用这个命令前需要先安装它的工具包 webp,按照如下几个步骤操作即可:

除了以上这种操作稍微麻烦的安装方式外,还可以使用 OS X 的包管理工具进行安装(你怎么不早说😭):

安装成功后,就可以愉快的使用 cwebp 命令了。来看看以下操作:

使用 cwebp 的默认压缩设置转换单张图片(默认是有损压缩,且默认的压缩的质量参数是 75):

cwebp images/flower.jpg -o images/flower.webp

使用 50 质量等级去转换单张图片:

cwebp -q 50 images/flower.jpg -o images/flower.webp

转换指定目录下的所有文件:

for file in images/*; do cwebp "$file" -o "${file%.*}.webp"; done

使用 Imagemin 转换图片

Imagemin Webp 插件可以在 Node 环境中独立使用,也可以结合 Webpack 等构建工具使用。通常只需要 10 行左右代码即可配置完成。

Node 环境下配置,以下代码会把 images 目录下的图片转成 WebP 图片后存到 compressed_images 目录下:

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');

imagemin(['images/*'], {
    destination: 'compressed_images',
    plugins: [imageminWebp({quality: 50})]
}).then(() => {
    console.log('Done!');
});

在构建工具 Webpack 下使用,这里还配合了 copy-webpack-plugin 插件实现图片的复制。以下代码来源于 webp-webpack

// Copyright 2018 Google LLC.
// SPDX-License-Identifier: Apache-2.0

const ImageminWebP = require('imagemin-webp');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');

module.exports = {
    entry: './index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new CopyWebpackPlugin([{
            from: './images/**/**',
            to: './images/[name].webp'
        }]),
        new ImageminPlugin({
            // imagemin-webp docs: https://github.com/imagemin/imagemin-webp
            plugins: [ImageminWebP({quality: 50})]
        })
    ]
}

你也可以尝试使用 imagemin-webp-webpack-plugin 这个插件,因为我看它最近 4 个月内有过更新,下载量也快 10K 了,应该可以满足需求。

对比 WebP 和 其他图片格式

下面我用 PS 做了一张图片:

然后用它导出了 4 张图片,它们的信息如下:

然后我用如下命令,批量将他们转成了 WebP 格式的图片:

for file in Downloads/img/*; do cwebp "$file" -o "${file%.*}.webp"; done

然后可以看到 Downloads/img/ 文件夹下所有文件的信息如下:

发现这 4 张图片被转成 WebP 格式的图片后文件大小居然都差不多大,大概都是 22KB,比原来真的小了太多了,尤其是 PNG 24 和 JPG 质量 100 的图片体积缩减更加明显。而最差的 JPG 质量 60 的图片再被转成 WebP 格式后,体积竟然还缩减了 54% 左右

接下来我们再把这 4 张图片通过在线工具 TinyPNG 压缩一下,以下是文件压缩后的信息(左右两列绿色数字分别表示:文件压缩前大小和压缩后大小):

发现 TinyPNG 对 PNG 24 和 JPG 质量 100 的图片压缩效果比较明显。另外将这压缩过的 4 张图片和 WebP 格式的图片(22KB)相比,发现 WebP 图片的文件大小还是明显小很多,小了超过 50%,所以这就是为什么建议在 Web 应用上使用 WebP 图片的原因,真的优化太大了。

让 WebP 图片在 Mac 下正常预览

从这往上翻的第二张图,可以发现 WebP 格式的图片在 Mac 下是无法正常预览的,所以需要给 Mac 加上这种能力。另外需要说一句 WebP 图片在 Chrome 下可以很好的支持了,直接将图片拖到浏览器中即可显示。

说到预览,看一下 WebP 在各浏览器下的兼容程度:

由上图可以看出,基本上现代浏览器已经能很好的支持 WebP 图片了,所以在生产环境上使用它是一点问题都没有。

Mac 需要正常预览 WebP 图片,可以在这里 qlImageSize 下载了 2 个插件来支持它:

下载完这 2 个插件包后,解压,然后把插件复制到对应的目录下保存:

这个时候 WebP 图片应该就能快速预览了,还不行的话就重启下访达进程(按住 option,同时鼠标右键点击访达,选择重新开启)。

兼容不同浏览器

如果你的网站对于不兼容 WebP 格式的图片的浏览器(比如 IE11)也有需求的话,那这里有一套方案可以让图片不会因为浏览器兼容性而显示出错:

<picture>
    <source type="image/webp" srcset="flower.webp">
    <source type="image/jpeg" srcset="flower.jpg">
    <img src="flower.jpg" alt="">
</picture>

对于上面这段代码,浏览器会首先检测是否支持 <source> 标签列表里的资源,如果兼容的话,默认会加载 flower.webp 图片,如果都不支持 <source> 列表里的资源的话,则会去加载 <img> 里指定的图片。

接下来该干什么

之前我做的项目里的图片基本都是 JPG\PNG 格式的,我找了一张我们网站首页的 Banner 图,就是那种 1920px 宽度的图片,它在被压缩工具压缩后文件大小还有 275 KB ,而当我用 cwebp 工具用 -q 75 的质量参数去转换成 WebP 图片后,你们知道它的文件大小变成多少了吗?它变成 50KB 😱

真的的不试不知道,一试吓一跳,原来 WebP 格式的图片能够带来这么大的优化效果,最关键的是 2 张图片用肉眼看起来显示效果差不多。

真的很棒 👍,WebP 凭借一己之力将网站的性能优化提高了一个档次。所以接下来 KPI 就有了:可以很愉快的把项目里所有的图片都转成 WebP 图片了。这么干完之后,你就可以和领导提涨薪了,领导领导我把我们网站优化了一下,性能提升了 10% ~ 20% 左右。不过接下来发生什么,可不要来找我哈。

参考文章

YMingF commented 1 year ago

不错