使用 WebP 图片

Katie Hempenius
Katie Hempenius

您为什么要关注?

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

  • YouTube 发现,切换到 WebP 缩略图后,页面加载速度提高了 10%
  • Facebook 体验到,当他们切换到使用 WebP 时,JPEG 的文件大小节省了 25-35%,PNG 的文件大小节省了 80%。

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/etc.)一起使用。这通常需要在构建脚本或构建工具的配置文件中添加约 10 行代码。以下是如何为 WebpackGulpGrunt 执行此操作的示例。

如果您没有使用这些构建工具中的任何一个,您可以将 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 标头

如果您有应用程序后端或 Web 服务器允许您重写请求,您可以读取 HTTP Accept 标头的值,它将声明支持哪些替代图片格式

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

读取此请求标头并根据其内容重写响应具有简化图片标记的好处。<picture> 标记在具有多个源时可能会变得相当长。以下是 Apache mod_rewrite 规则,可以提供 WebP 替代方案

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 提供的图片。