站点运营

站点运营:传输压缩自查,别让 HTML 和 CSS 以原始体积发送

文本类资源不压缩就发送,等于让访客和蜘蛛多等几倍时间。这篇讲怎么确认服务器与 CDN 是否真的在压缩、哪些文件该压、哪些别压,以及 Vary 头、预压缩文件和压缩级别这些容易被忽略的细节,附一份可照着走的自查清单。

站点运营

站点运营:传输压缩自查,别让 HTML 和 CSS 以原始体积发送

HTML、CSS、JavaScript 这类文本文件有个特点:重复字符多、可预测性高,压缩率通常能到 60% 以上。也就是说,一个 100KB 的 HTML 页面,压缩后可能只有 20 到 30KB。如果服务器没有开启压缩,这部分体积就原样发给了访客和蜘蛛,属于白白浪费的等待时间。

这件事值得单独拿出来查一次,因为它成本极低、影响面却覆盖全站每一个页面。

先确认:到底压了没有

别只看配置文件,要看真实响应。最简单的做法是用命令行工具请求两次:一次带上 Accept-Encoding: gzip 请求头,一次不带,然后对比两次响应的 Content-Encoding 和 Content-Length。

  • 带压缩请求头时,响应里应该出现 Content-Encoding: gzip 或 Content-Encoding: br。
  • 不带时,体积应明显更大;如果两者体积完全一样,基本说明压缩没生效。
  • 浏览器开发者工具的 Network 面板里,Size 一列通常显示传输体积,Content 一列显示解压后体积,差异就是压缩收益。

抽查对象不要只挑首页,至少覆盖:首页、一个栏目列表页、一篇内容页、一个 CSS 文件、一个 JS 文件、站点地图文件。

哪些类型该压,哪些别压

大体原则是:文本类压缩收益高,二进制已压缩格式压了也白压。

  • 建议开启:text/html、text/css、application/javascript、application/json、image/svg+xml、XML(含站点地图和 RSS)。
  • 不必开启:JPEG、PNG、WebP、AVIF、MP4、WebM、WOFF2、ZIP 等。这些格式本身已经过压缩,再走一遍 gzip 只是消耗 CPU,体积几乎不会变小。

动态压缩与预压缩的选择

动态压缩是每次请求时现场压一遍,配置简单但吃 CPU;预压缩则是提前把 .gz 或 .br 文件生成好放在同目录,请求时直接发送,几乎零开销。流量较大的站点,建议静态资源走预压缩,动态页面再考虑动态压缩。

无论用哪种方式,运营上要留意一件事:内容更新后,旧的预压缩文件有没有跟着重新生成。改了 CSS 却还在发旧的压缩文件,前端表现就会对不上。

别漏掉 Vary 响应头

如果 CDN 或反向代理是按 URL 缓存,却没有区分压缩与非压缩版本,就可能把压缩版发给不支持的客户端,或者把未压缩版发给所有客户端。加上 Vary: Accept-Encoding,或者干脆让 CDN 统一负责压缩、源站关闭压缩,都是可行做法,但不要两层同时压。

压缩级别的取舍

级别不是越高越好。gzip 一般设在 5 到 6 已经接近收益上限,Brotli 质量设 4 到 6 性价比通常较好。再往上调,体积减少有限,CPU 占用却明显上升,高峰期容易变成瓶颈。

一份可照着走的自查清单

  1. 抽查各类资源的响应头,确认有 Content-Encoding。
  2. 确认源站与 CDN 没有重复压缩,避免二次压。
  3. 确认响应头里有 Vary: Accept-Encoding,缓存不会串味。
  4. 确认缓存策略对压缩版本和非压缩版本的处理一致。
  5. 确认静态资源有预压缩文件,且内容更新后会重新生成。
  6. 确认极小文件(1KB 以下)不必强压,收益有限。
  7. 换服务器、换 CDN、调整缓存规则后,重新验证一遍。

几个常见误区

  • 以为配置文件里写了 gzip on 就万事大吉,没看真实响应。
  • 只压了 HTML,漏掉 CSS、JS、JSON 和站点地图。
  • 对图片再压一次,徒增 CPU 开销。
  • 在源站开了压缩,CDN 又压一遍,结果头部信息混乱。

传输压缩算不上什么高级技巧,更像一次性的基础设施检查。花十几分钟确认一遍,把这几个检查点写进运维清单,之后每次环境变更时复测一次就够了。