Gzip 与 Brotli 压缩对网页加载速度的实测对比

Gzip 与 Brotli 实测对比封面

为什么还要再做一次 Gzip 与 Brotli 的实测对比

网上关于 Gzip(一种基于 DEFLATE 算法的通用 HTTP 内容压缩格式)与 Brotli(谷歌在 2015 年推出、专为 HTML/CSS/JS 文本优化的压缩格式)的对比文章已经很多,但大多停留在算法原理或单文件压缩率层面。真正影响页面打开速度的因素是端到端的:服务端 CPU 时间、网络传输字节数、客户端解压耗时三者之和,缺少任何一个维度,结论就容易跑偏。本文将教你如何在自己的站点上跑一次可复现的实测,并解决”看起来都开了、但首屏没变快”这种最常见的问题。

如何判断你的站点值得换 Brotli?两个简单指标:HTML、CSS、JS 三类文本资源占总传输大小超过 40%,且站点定位面向海外用户(Brotli 在所有主流浏览器都已支持,但部分国内 CDN(内容分发网络,把静态资源缓存到全球边缘节点的服务)边缘节点对 Brotli 回源还不完整)。命中其一就值得做这次评估。如果你的页面里图片和视频占绝对大头,那压缩算法的差异就只能影响很小一部分字节,优先级应该让位给图片优化和懒加载。

实测环境:一台 VPS,三种压缩组合

为了让数据可比,所有测试都在同一台机器上完成。VPS(Virtual Private Server,虚拟专用服务器,独享 CPU 与内存配额并带独立公网 IP)位于美国西海岸,配置 2 核 4G、SSD,软件栈是 Nginx 1.24 加 PHP 8.2 加 WordPress 6.5。测试页面是一个典型的内容站首页,未压缩总传输大小 624 KB,其中 HTML 32 KB、CSS 168 KB、JS 312 KB、图片 112 KB。

三组对照配置如下:

  • 组 A:完全不开压缩,作为基准
  • 组 B:仅开 Gzip,gzip_comp_level 6(Nginx 默认值)
  • 组 C:仅开 Brotli,brotli_comp_level 6(推荐起步值)
  • 组 D:Brotli 静态预压缩,提前生成 .br 文件,运行时直接发送

每组分别从三个地理位置发起 50 次请求取中位数:洛杉矶同机房、北京电信家用宽带、法兰克福云主机。请求间隔 2 秒以避免触发限流,整套数据当天跑完,避免跨日的网络波动干扰对比。

关键数据:传输字节、TTFB、首屏完成时间

直接看核心三项指标的中位数。总传输大小这一项:基准 624 KB、Gzip 198 KB、Brotli-6 172 KB、Brotli 预压缩 169 KB。服务端 TTFB(首字节时间)这一项:基准 142 ms、Gzip 156 ms、Brotli-6 178 ms、Brotli 预压缩 144 ms。北京客户端首屏完成时间这一项:基准 2840 ms、Gzip 1820 ms、Brotli-6 1690 ms、Brotli 预压缩 1610 ms。

可以看出几个反直觉的细节。第一,Brotli 比 Gzip 的传输字节减少只有 13%,远不到很多文章说的”压缩率提升 20-30%”,原因是站点 JS 已经做过 minify,进一步压缩的空间被吃掉了。第二,运行时 Brotli 的 TTFB 比 Gzip 还多 22 ms,这就是它对服务端 CPU 更敏感的体现,对低配机器尤其明显。第三,预压缩组的 TTFB 几乎与 Gzip 持平,同时享受最小的传输字节,是综合最优解。

压缩级别怎么选:不要直接拉到最高

Brotli 支持 0 到 11 共 12 个级别,Gzip 支持 1 到 9 共 9 个级别。新手最常见的错误是直接把级别拉到最高,结果服务端 CPU 飙升、TTFB 反而劣化,原本想优化速度反而被压缩自己拖慢。

在同一台机器上额外测了 Brotli 各级别压缩同一个 168 KB CSS 文件的服务端 CPU 时间:

  • 级别 4:3.1 ms,压缩后 41.2 KB
  • 级别 6:5.8 ms,压缩后 39.8 KB
  • 级别 8:18.4 ms,压缩后 38.9 KB
  • 级别 11:186 ms,压缩后 38.1 KB

可以看出从级别 6 到 11,压缩率只提升 4%,CPU 时间却涨了 32 倍。结论很清晰:动态内容用 6,静态资源用预压缩 11,把昂贵的高级别压缩放到构建期一次性付出,运行时就零开销了。

配置落地:Nginx 与 Apache 的关键参数

Nginx 启用 Brotli 需要 ngx_brotli 模块,许多发行版的默认包并未带,要么换用 OpenResty,要么自己编译。核心配置只有四行:brotli on、brotli_comp_level 6、brotli_static on,以及 brotli_types 列出 text/html、text/css、application/javascript、application/json、image/svg+xml 等文本类型。注意不要把 image/jpeg、image/webp 等已经压缩过的格式塞进 brotli_types,那只会徒增 CPU 又拿不到任何字节收益。

Apache 用户走 mod_brotli,同样要注意 AddOutputFilterByType 只覆盖文本类型。两边的共同坑是 Vary 响应头,必须返回 Vary: Accept-Encoding,否则中间代理可能把 Brotli 内容缓存给只支持 Gzip 的客户端,导致页面打不开或样式错乱。

如果你的站点托管在共享主机上,没有 root 权限装模块,可以考虑回退到 Gzip 加合理的 minify 加 HTTP/2,对最终用户体验影响其实不大。WordPress 性能这块还可以参考 W3 Total Cache 调优实战 配合使用。

与 CDN 和 HTTP/2 协同:别让链路抵消收益

很多人开了 Brotli 却没快多少,问题往往出在链路上。CDN 边缘节点如果只对 Gzip 做了缓存,那源站发出的 Brotli 在过缓存时会被丢弃或重新用 Gzip 压缩。解决方法是在 CDN 控制台开”按 Accept-Encoding 分键缓存”,或者直接选用支持 Brotli 透传的厂商。

另一个常见盲点是 HTTP/2。Brotli 与 HTTP/2 多路复用配合时收益最大,因为后者减少了连接建立和头部开销,让”压缩省下的字节”更直接地转化为更快的首屏。如果你的源站还在 HTTP/1.1 加 Keep-Alive,建议先把 HTTP/2 打开再谈 Brotli。

主机选型方面,香港和美国的 VPS 通常都默认支持 HTTP/2 与现代加密库,相关选型要点见 美国 VPS 部署教程WordPress 香港主机指南;做弹性扩容时云服务器(基于虚拟化资源池按需开通、按用量计费的服务器)更合适,思路见 云服务器选购指南;更多调优案例可以浏览 WordPress 分类文章列表

总结

Gzip 与 Brotli 的差距在真实站点上没有教科书数据那么夸张,关键收益来自”静态资源预压缩加 CDN 正确分键缓存加 HTTP/2″的组合拳。建议你按这套方案落地:动态内容继续用 Gzip 或 Brotli-6,静态资源在构建期生成 .br 文件,CDN 层确认按编码分键,最后用真实地理位置的客户端复测一次。如果你打算把整套压缩策略部署到独立公网 IP 的环境,可以考虑 Hostease 的香港或美国 VPS,对 Brotli 模块与 HTTP/2 的兼容性都不错。

发表评论