1、压缩基础:为什么需要压缩?压缩比与性能的权衡、常见压缩算法概览

大家好,我是你们这堂《资源压缩性能优化实战》课的主讲。咱们开门见山,先聊聊最基础的问题——为什么要压缩?

你可能觉得这问题太简单了。压缩嘛,就是让文件变小,省带宽、省流量。没错,但我想让你换个角度想:压缩的本质,是用计算时间换存储空间和传输时间。说白了,就是让 CPU 多干点活,换来更快的网络加载和更小的磁盘占用。

我在几年前优化一个大型电商首页时,就吃过没做压缩的亏。一个页面光 JS 和 CSS 加起来就快 2MB,用户打开要等 5 秒以上。后来上了 Gzip,直接砍到 600KB,加载时间降到 1.5 秒。你看,这就是压缩的威力。

1.1 压缩比与性能的权衡

压缩不是免费的午餐。你压得越狠,CPU 消耗就越大,解压时间也越长。这里有个关键概念叫压缩比——原始大小除以压缩后大小。压缩比越高,文件越小,但压缩和解压的耗时通常也越长。

核心权衡点:

  • 高压缩比:文件更小,传输更快,但服务端压缩耗时增加,客户端解压耗时也增加
  • 低压缩比:文件较大,传输较慢,但压缩和解压都很快
  • 最佳平衡点:取决于你的场景——静态资源可以接受更高的压缩级别,实时 API 响应则要优先考虑速度

我记得有一次,团队里有人把 Nginx 的 Gzip 压缩级别设成了 9(最高级)。结果呢?静态资源确实小了不少,但每次请求都要等服务器压缩半天,用户反而觉得更慢了。后来我建议改成 5 级,文件只大了 5%,但响应时间快了 40%。

你想想看,压缩级别从 1 到 9,压缩比提升是递减的,但 CPU 开销是递增的。这就是典型的边际效益递减。

压缩级别 压缩比(Gzip) 压缩耗时(ms) 解压耗时(ms) 推荐场景
1-3 2.5x - 3.0x 10-30 5-10 实时 API、动态页面
4-6 3.0x - 4.0x 30-80 10-20 静态资源、CSS/JS
7-9 4.0x - 4.5x 80-200 20-40 预压缩、构建产物

我的建议:对于 Web 静态资源,Gzip 级别 5-6 是最稳妥的选择。如果你用 Brotli,级别 4-5 通常就够了。别盲目追求最高压缩比,除非你提前预压缩好文件。

1.2 常见压缩算法概览

目前主流的压缩算法有三个:Gzip、Brotli 和 Zstd。它们各有各的脾气,咱们一个一个聊。

Gzip —— 老牌劲旅

Gzip 诞生于 1992 年,可以说是压缩界的「老兵」。它基于 Deflate 算法,兼容性极好——几乎所有浏览器和服务器都支持。我在项目中最早用的就是它,稳如老狗。

但 Gzip 也有短板:压缩比相对一般,对文本类资源效果不错,但对二进制文件(如图片、视频)基本没什么用。嗯,这里要注意,不要对已经压缩过的格式(JPEG、PNG、MP4)再套 Gzip,只会浪费 CPU。

Brotli —— 后起之秀

Brotli 是 Google 在 2015 年推出的算法,专门为 Web 内容优化过。它比 Gzip 的压缩比高 20%-30%,尤其对 HTML、CSS、JS 这类文本资源效果拔群。

我个人习惯在 Nginx 里同时开启 Gzip 和 Brotli,让浏览器自己协商。支持 Brotli 的浏览器就用 Brotli,不支持的 fallback 到 Gzip。这样既保证了兼容性,又能享受更好的压缩效果。

避坑指南:我曾经在配置 Brotli 时忘了设置压缩级别,默认用了 11 级。结果服务器 CPU 直接飙到 90%,页面加载反而变慢了。后来我把级别降到 4,CPU 降到了 20%,压缩比只差了 5%。记住:Brotli 级别 4-5 是 Web 场景的黄金区间。

Zstd —— 性能怪兽

Zstd(Zstandard)是 Facebook 在 2016 年开源的算法。它的特点是:压缩速度极快,解压速度更快。在同等压缩比下,Zstd 的压缩速度是 Gzip 的 2-3 倍,解压速度是 Gzip 的 5-10 倍。

不过 Zstd 目前浏览器原生支持还不够广泛,更多用在服务端内部通信、数据存储、日志压缩等场景。如果你在做微服务间的数据传输,Zstd 是个非常好的选择。

算法 压缩比(文本) 压缩速度 解压速度 浏览器支持 推荐场景
Gzip 3.0x - 4.0x 中等 快 全部 通用 Web 资源
Brotli 4.0x - 5.5x 慢(高等级) 快 Chrome、Firefox、Edge、Safari 静态资源、HTTPS 场景
Zstd 3.5x - 5.0x 极快 极快 有限(需 polyfill) 服务端通信、数据存储

1.3 压缩算法选择框架

说了这么多,到底该怎么选?我画了一张图,帮你快速决策。

压缩算法选择框架 压缩算法选择决策树 资源需要压缩? 是 → 判断资源类型 文本类(HTML/CSS/JS) 浏览器端 → Brotli 服务端 → Zstd 二进制(图片/视频/音频) 已压缩格式 → 不压缩 原始格式 → 用专用工具 否 → 跳过压缩 💡 决策要点: • 文本类资源优先使用 Brotli(浏览器)或 Zstd(服务端) • 已压缩的二进制格式(JPEG/PNG/MP4)不要二次压缩 • 实时场景用低压缩级别,静态资源用高压缩级别

1.4 实际项目中的选择建议

说了这么多理论,咱们落地到实际项目里。我根据不同的场景,给你几个可以直接用的方案:

  • Web 前端静态资源:用 Brotli 级别 4-5,fallback 到 Gzip 级别 5-6。构建时预压缩好,运行时直接返回压缩文件。
  • API 响应:用 Gzip 级别 3-4,或者 Zstd 级别 3。追求速度,别让用户等太久。
  • 服务端内部通信:用 Zstd 级别 3-5。速度快,压缩比也不错。
  • 日志归档:用 Zstd 级别 10-15。反正是一次性压缩,追求极致压缩比。
  • 数据库备份:用 Zstd 级别 19。压缩比最高,备份文件能小很多。

一个小技巧:如果你用 Nginx,可以同时开启 Gzip 和 Brotli 模块。Nginx 会根据请求头中的 Accept-Encoding 自动选择最优算法。配置大概长这样:

gzip on;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript;

brotli on;
brotli_comp_level 4;
brotli_types text/plain text/css application/json application/javascript;

好了,这一章的内容就到这里。压缩基础搞清楚了,后面咱们才能深入聊具体的优化技巧。记住一句话:压缩不是万能药,但不用压缩是万万不能的。