使用 WebP 图片

Katie Hempenius
Katie Hempenius

为什么您应该关注?

WebP 图片比 JPEG 和 PNG 图片小,文件大小通常会缩减 25-35%。这会减小页面大小并提高性能。

WebP 是 JPEG、PNG 和 GIF 图片的绝佳替代格式。此外,WebP 还提供无损压缩和有损压缩。在无损压缩中,不会丢失任何数据。有损压缩会减小文件大小,但可能会降低图片质量。

将图片转换为 WebP 格式

人们通常使用以下方法之一将图片转换为 WebP:cwebp 命令行工具或 Imagemin WebP 插件(npm 软件包)。如果您的项目使用构建脚本或构建工具(例如 Webpack 或 Gulp),Imagemin WebP 插件通常是最佳选择;而对于小型项目或只需转换一次图片的情况,CLI 是不错的选择。

将图片转换为 WebP 时,您可以选择设置各种压缩设置,但对于大多数人来说,唯一需要关注的是质量设置。您可以指定 0(最差)到 100(最好)之间的质量级别。您可以尝试不同的设置,找到在图片质量和文件大小之间达到最佳平衡的级别,以满足您的需求。

使用 cwebp

使用 cwebp 的默认压缩设置转换单个文件:

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 插件可以单独使用,也可以与您喜爱的构建工具(Webpack/Gulp/Grunt 等)搭配使用。这通常涉及向构建脚本或构建工具的配置文件添加大约 10 行代码。

如果您没有使用这些构建工具,则可以将 Imagemin 本身用作 Node 脚本。此脚本会转换 images 目录中的文件,并将其保存在 compressed_images 目录中。

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

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

提供 WebP 图像

如果您的网站仅支持与 WebP 兼容的浏览器,则可以停止阅读。否则,请向较新的浏览器提供 WebP,向较旧的浏览器提供后备图片:

之前:

<img src="flower.jpg" alt="">

之后:

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

<picture>、<source> 和 <img> 标记(包括它们彼此之间的顺序)都会相互作用,从而实现最终结果。

<picture>

<picture> 标记为零个或多个 <source> 标记以及一个 <img> 标记提供封装容器。

<source>

<source> 标记用于指定媒体资源。

浏览器会使用列表中第一个格式受支持的来源。如果浏览器不支持 <source> 标记中列出的任何格式,则会回退到加载 <img> 标记指定的图片。

<img>

<img> 标记可使此代码在不支持 <picture> 标记的浏览器上运行。 如果浏览器不支持 <picture> 标记,则会忽略不支持的标记。因此,它只会“看到”<img src="flower.jpg" alt=""> 标记并加载该图片。

读取 HTTP Accept 标头

如果您有应用后端或网络服务器,可以重写请求,则可以读取 HTTP Accept 标头的值,该值会通告支持哪些替代图片格式:

Accept: image/webp,image/svg+xml,image/*,*/*;q=0.8

读取此请求标头并根据其内容重写响应,有助于简化图片标记。如果来源较多,<picture> 标记可能会变得很长。以下是可提供 WebP 替代格式的 Apache mod_rewrite 规则:

RewriteEngine On
RewriteCond %{HTTP:Accept} image/webp [NC]
RewriteCond %{HTTP:Content-Disposition} !attachment [NC]
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f [NC]
RewriteRule (.+)\.(png|jpe?g)$ $1.webp [T=image/webp,L]

如果您采用这种方法,则需要设置 HTTP Vary 响应标头,以确保缓存能够理解,图片可能会根据 Accept 标头以不同的方式提供:

<FilesMatch ".(jpe?g|png)$">
  <IfModule mod_headers.c>
    Header set Vary "Accept"
  </IfModule>
</FilesMatch>

之前的重写规则会查找所请求的任何 JPEG 或 PNG 图片的 WebP 版本。如果找到 WebP 替代图片,系统会使用适当的 Content-Type 标头提供该图片。这样,您就可以使用类似于以下内容的图片标记,并自动支持 WebP:

<img src="flower-320w.jpg" srcset="flower-320w.jpg 320w, flower-640w.jpg 640w, flower-960w.jpg 960w">

验证 WebP 使用情况

Lighthouse 可用于验证您网站上的所有图片是否都使用 WebP 格式。运行 Lighthouse 性能审核(Lighthouse > 选项 > 性能),然后查看采用新一代格式提供图片审核的结果。Lighthouse 会列出所有未以 WebP 格式提供的图片。