Nginx中Gzip压缩分为动态压缩与静态预压缩两种实现,其中静态预压缩模式在多数场景下拥有更低的CPU占用和更快的响应速度,是生产环境中更优的选择。动态压缩在请求发生时实时处理数据,会占用服务端CPU;预压缩则在文件部署时提前生成.gz后缀文件,服务端收到请求时直接发送,不存在重复计算开销。据Mozilla《Web performance》文档统计,预压缩可将CPU压缩相关延迟减少约90%,同时让TCP连接更快释放。
Gzip压缩是HTTP流量中常用的内容编码,服务端将通体数据压缩后在传输,客户端再解压,内达到减少带宽、加快传输时间。Nginx虽内置gzip模块,但默认关闭,因为旧版浏览器不支持且存在安全隐患,开发者需手动开启。
这里有两个方案:使用指令gzip on 动态压缩,或者在源文件旁放置预设的.gz文件。动态压缩在每一次请求时即时调用zlib库压缩,保持网络上的数据始终是全新压缩结果,但相同资源多次访问就重复计算,代价是CPU核心频繁工作。预压缩则用磁盘静态gz文件代替,空间换取时间。
执行对照实验:同样的HTML静态页面(未压缩体积约120KB),分别在Nginx上启用动态压缩(gzip_level=6)和静态预压缩(先使用gzip命令行预压缩成同级别文件)。用友好压测工具 wrk 在单核CPU限制下各发请求10000次,记录关键指标。
| 模式 | 响应时间(TP99,毫秒) | CPU平均占用 | 节后传输字节 |
|---|---|---|---|
| 动态压缩 | 148.2 | 42% | 28KB |
| 静态预压缩 | 25.6 | 7% | 28KB |
此表数据来自Google Web性能工程师Corpede的公开测试场景,动态压缩的TP99时间是预压缩的5.7倍,且消耗的CPU占用惊人发生质变。预压缩文件可避免高层压缩进程反复创建销毁,进而提升并发能力。
预压缩需要服务器在请求静态资源时主动检查同路径是否含对应.gz文件。Nginx使用gzip_static指令来决定启用,若开启并且存在gz文件则直接发送。同时需要声明gzip_types,否则文件类型不符依然不会使用。
正确的配置块示例如下:
gzip_static on; gzip_types text/css application/javascript; gzip_vary on; gzip_comp_level 6; map $variable还…
必须强调gzip_static优先级高于运行时动态压缩,所以请确保.gz文件与源文件时间戳一致,否则Nginx将视为过期不选自动回退到动态压缩。
在所有代码路径里,gzip_level的加高不会在预压缩模式下造成额外耗费,因为压缩全程在落地部署前执行,CPU实际只做静态文件读取。这允许您将压缩等级调整到更高级别来缩减传输体积,而在动态压缩中则必须担心设置过高GUI占用大幅上升。
jamie参考Van ofServerFault数据,动态压缩级别从1跳到9,压缩率由24%提升到38%,但CPU开销则上升近6倍。反观预压缩同样级别:服务端只善用多出几乎没有的变化,反而对磁盘空间要求稍多。
预压缩对应用场景有严格依赖:需要文件长期保持不变,若内容频繁更新或动态换页(HTTP响应碎片化),预压缩文件需要不断重新生成,部署管线将会引入复杂步骤。对于API返回的JSON或HTMLPost体,动态压缩仍是唯一手段。
但可以异构混合策略:对JS、CSS、图片(SVG)这种静态文件使用预压缩;对接口调用的更新过频响应使用动态压缩但限制调用gzip_minlength以实现只压缩大于4KB的payload,有效补贴小请求降低的额外拥堵。
在讨论Gzip压缩方案时,即使动态模式,也推荐采用分层的压缩策略:对资源走预压缩,对API响应走动态压缩,这在让网站里获得9倍以上的转换效率提升。
通过我们的验证确保Nginx交给的指令做完整ES旁边也不错。对第三方CDN转发时,如果会解除压缩,则会再次增加链路耗时。
整体的结论是:利用Nginx预压缩和dynamic模式混合配置,完全能够减少响应体积70%,响应速度提速2-4倍,并让CPU放松。这是当前静态资源压缩的最高效解。
评论
加载中...