FlowingDev

WebP 原理详解:给 Web 成功瘦身的百变图像格式

了解 WebP 如何利用预测视频编码(predictive video coding),在不损失画质的前提下,把图片压得比 JPEG 和 PNG 还要小,为 Web 节省救命的带宽。

试用工具: WebP 转换器

一句话总结

WebP 是 Google 捣鼓出来的一种现代图像格式,它白嫖了视频压缩里的各种骚操作,把图片硬生生压得比 JPEG 或 PNG 小得多,同时肉眼看起来画质还一模一样。

它解决了什么痛点

很长一段时间以来,互联网的视觉体验都是靠两大对立阵营——JPEG 和 PNG——之间那紧张又脆弱的休战协议来维持的。(GIF 当然也在,不过是在角落里瞎嚷嚷,这咱待会儿再说)。

如果你有一张色彩斑斓的摄影照片,你用 JPEG。JPEG 是 lossy(有损的),意思是它会偷偷扔掉那些“按理说你眼睛看不出来”的数据来节省空间。如果你有一个 Logo、清晰的文本,或者需要透明背景,你用 PNG。PNG 是 lossless(无损的)——它让每个像素都保持完美,但代价就是文件体积大得吓人。如果你还想要动图?那你得用 GIF,一个诞生于 1987 年的老古董,效率低得令人发指,还只能显示 256 种颜色。

痛点在于,图片逐渐膨胀到了占普通网页下载字节数 60% 以上的地步。随着世界从用宽带的台式机转向在信号断断续续的 3G 网络下冲浪的手机,这些臃肿的图像格式成了一个巨大的累赘。图片加载慢意味着用户心态爆炸、购物车被抛弃,整个 Web 冲浪体验就像在泥沼里跋涉一样黏糊糊的。

到了 2010 年左右,Google 觉得这种双格式系统简直没救了。他们当时刚收购了 On2 Technologies,一家开发了名为 VP8 视频压缩格式的公司。Google 的工程师们突然灵光一闪:视频不就是快速播放的静态图片嘛?如果我们把牛逼哄哄的 VP8 video codec(视频编解码器)里“静态图片”那部分抠出来,单独打包成一个图片文件会怎样?

于是,WebP 诞生了。它的使命就是“One format to rule them all(一统江湖)”。它不仅支持能把 JPEG 按在地上摩擦的 lossy 压缩,支持秒杀 PNG 的 lossless 压缩,支持透明度(alpha channels),甚至还能做动图,终于可以把 GIF 送去养老了。

扒一扒底层原理

想要搞懂为啥 WebP 这么高效,你得看看它是怎么“作弊”的。它实际上并没有逐个像素地存储你的图片;它存的是一堆指令,用数学方法去“猜”你的图片长什么样。

有损压缩 (Lossy Compression):Predictive Coding(预测编码)

当 WebP 在“lossy”模式下运行(也就是作为 JPEG 的替代品时),它使用了 predictive coding,这招是从 VP8 视频编解码器里原封不动继承过来的。

WebP 把你的图片切分成许多“macroblocks(宏块)”——16x16 或 4x4 像素的网格。WebP encoder(编码器)并没有独立保存一个块里每个像素的颜色,而是去偷瞄当前块正上方和正左方的块。它会问自己:“基于我已经画出来的像素,我能不能猜出下一个块长啥样?”

因为大多数照片都有大片连续的色彩(比如蓝天、光滑的脸颊或者阴影),这种预测往往非常准。接着,WebP 只保存 residual(残差)——也就是它的预测值和实际图像之间的数学差值。

只需要保存这些微小的差值,而不是完整的像素数据,WebP 就能大幅度地压缩文件体积。

无损压缩 (Lossless Compression):完全不同的怪兽

Lossless 模式下的 WebP(也就是 PNG 的替代品)并没有用 VP8。它用的是 Google 专门为 WebP 设计的另一套完全不同的技术。它依赖于一个多阶段的处理流程:

  1. Spatial Prediction(空间预测): 就像它那个 lossy 兄弟一样,它试图根据邻居来预测像素。
  2. Color Transform(颜色变换): 它把颜色数据分离开来,寻找冗余信息。
  3. Green is King(绿色为王): 它把 green channel(绿色通道)作为基准,根据绿色的值来预测红色和蓝色的值(因为人类眼睛对绿色最敏感)。
  4. LZ77 压缩: 最后,它拿着这些优化过的数据,跑一遍高级版的 LZ77 字典压缩算法。

文件结构 (RIFF)

在这一切底层,WebP 被包装在一个叫做 RIFF (Resource Interchange File Format) 的轻量级容器里。RIFF 是一种打过标签的文件结构,这意味着 WebP 文件被组织成一个个的 chunks(数据块)。这使得该格式能够轻松追加元数据(比如你相机的 EXIF 数据)或 ICC 颜色配置文件,而不会搞坏核心图像数据。

特性 JPEG PNG GIF WebP
Lossy Compression (有损压缩) Yes No No Yes
Lossless Compression (无损压缩) No Yes Yes Yes
Transparency (Alpha通道) No Yes 1-bit Yes (Lossy & Lossless 均可)
Animation (动画) No No Yes Yes
Average Saving (平均体积节省) Baseline Baseline Baseline ~小 25-34%

真实世界的填坑故事

电商雪崩事件

一家中型在线服装零售电商发现他们在移动设备上的跳出率奇高。经过审查发现,他们的商品目录页面竟然要下载将近 15 MB 的高清 JPEG。移动端浏览器把时间全花在解析那些巨大无比的羊毛衫照片上了。

工程师团队搞了一个自动化 pipeline,用来给支持的浏览器提供 WebP 图片。通过调整 lossy 压缩的参数,他们不仅完美保留了展示面料纹理所需的清晰度,还把页面的总 payload 降到了 3.5 MB。页面加载时间暴跌了 4 秒。结果就是,移动端的转化率猛增了 18%。

踩坑经验: 图片的 byte 数和你的收入是成反比的。只要你给用户发稍微小点的文件,他们就有足够的耐心留下来掏钱。

透明的 Hero Image

一位网页设计师为一个新的 SaaS 产品精心制作了一个极其漂亮的 landing page。Hero 区域(首屏大图)有一个非常复杂的 3D 服务器机柜插画,悬浮在一个酷炫的 CSS 动态渐变背景之上。要实现这个效果,服务器机柜的图片必须是透明背景。

设计师把它导出成带 alpha channel 的 PNG-24。由于 3D 渲染复杂的阴影和上百万种颜色,这张 PNG 居然有 2.2 MB 这么大。加载这玩意儿感觉像是拨号上网拨回了 2004 年。

开发老哥拿到这只 PNG,随手转成了 WebP。他们用了一个 WebP 特有的超能力:lossy RGB 配合 lossless Alpha channel。这意味着颜色部分像 JPEG 一样被狠狠压缩,但透明部分却依然保持像素级完美,没有任何锯齿边缘。结果生成的 WebP 文件只有 210 KB——体积缩减了 90%,肉眼画质完全没掉。

踩坑经验: 你再也不需要在“色彩丰富逼真的照片”和“透明背景”之间做单选题了。WebP 小孩子才做选择,全都要。

表情包泛滥的博客

一个很火的流行文化博客严重依赖 GIF 动图来展示电影片段和夸张的 reaction 表情包。一篇文章里可能就有 5 个 GIF,一口气吃掉 20 MB 流量,还让那些老掉牙的笔记本电脑听起来像喷气式飞机要起飞一样,因为 CPU 为了解码这个上古格式已经快要冒烟了。

后来他们把整个媒体库都迁移到了 Animated WebP(WebP 动图)。因为 GIF 是把每一帧都当成一张完整的图片来存,而 Animated WebP 却用了类似视频的压缩方式,只存帧与帧之间的差异,这省出来的空间简直是天文数字。一个 5MB 的 GIF 变成了 800KB 的 WebP。CPU 占用率也呈断崖式下跌。

踩坑经验: GIF 这东西就该呆在博物馆里。要在 Web 上放简短循环的动画,像 WebP(或者真正的 MP4/WebM 视频)这样的现代格式绝对是降维打击。

常见的翻车姿势和陷阱

  • 双重 Lossy 的陷阱 (The Double-Lossy Trap): 把一张已经被压出包浆、满是 artifact(伪像)的 JPEG 转换成 lossy WebP 绝对是个烂主意。WebP 的算法实际上会试图完美地保留那些丑陋的 JPEG 马赛克块,把它当成图像本身的一部分,这反而会导致文件体积更大或者画面更糊。一定要尽可能从最高画质的源文件(比如 RAW 文件、高分辨率 PNG 或未压缩的原版 JPEG)开始转换。
  • 忘记用 HTML 的 <picture> 标签: 虽然今天 WebP 已经在全球享有了大约 97% 的浏览器支持率,但在很长一段时间里,它只是 Google 自己人的狂欢。Apple 的 Safari 直到 2020 年底才慢吞吞地加上了对 WebP 的支持。如果你还需要支持上古时代的浏览器,你可不能只在 <img> 标签里硬塞一个 .webp。你必须用 <picture> 标签来提供个 fallback(优雅降级):
    <picture>
      <source srcset="image.webp" type="image/webp">
      <img src="image.jpg" alt="A reliable fallback">
    </picture>
    
  • 以为 WebP 总是最小的: WebP 确实很棒,但它也不是什么魔法。对于极其简单、扁平化颜色的矢量图形(比如极简风 Logo),SVG 几乎总是更小,而且还能无限缩放。同样地,像 AVIF 这样的下一代新格式在纯压缩率上经常暴打 WebP,尽管 AVIF 的编码需要消耗大得多的算力。
  • 忽视了服务器上的编码时间: WebP 压缩时消耗的 CPU 算力比 JPEG 高得多。如果你在用户请求图片时进行 on-the-fly(即时)生成 WebP,那编码所需的 CPU 时间反而可能导致延迟,把你省下带宽带来的优势全抵消了。WebP 转换应该提前搞定(在构建阶段,或者在用户上传图片时异步处理),而不是在第一次渲染时动态去转。

为什么它必须在你的技术雷达里

如果你是搞 Web 开发的,那么 Web 性能早就不是什么锦上添花的奢侈品了;它是硬核刚需。像 Google 这样的搜索引擎会在排名上主动惩罚慢吞吞的网站,并且极其看重被称为 Core Web Vitals(核心 Web 指标)的参数(特别是 Largest Contentful Paint,简称 LCP)。因为屏幕上的“最大内容”通常就是一张图片,所以优化这张图片是提升 SEO 最快、最直接的手段。

此外,带宽就是要烧钱的——无论是对你(AWS 的出网流量费可是出了名的坑爹),还是对身处发展中国家、用着计费流量套餐的用户来说,都是如此。

在 21 世纪 20 年代,无论是处理用户上传的头像、海量的营销落地页、相册画廊,还是电商商品目录,WebP 都是那个默认、最实在的选择。它在广泛的浏览器兼容性、极佳的视觉质量和逆天的文件体积缩减之间,找到了最佳的平衡点。

深入折腾

理论搞定,动手试试吧——100% 在你的浏览器中运行。

试用工具: WebP 转换器