直接读取预压缩文件(.gz或.br)是最优实践,需严格区分:gzip_static服务.gz文件且仅限location块启用;brotli_static always服务.br文件但须https、关闭gzip相关配置,并在http/server顶层启用;两者互斥,构建阶段必须同步产出对应压缩文件。

直接读取预压缩文件(.gz 或 .br)是降低 Nginx CPU 压力、提升静态资源响应速度最有效的做法。它不依赖运行时压缩计算,而是由构建阶段产出对应压缩文件,Nginx 在请求时“零开销”返回。但两种机制不能混用,需按类型和协议严格区分。
启用 gzip_static:服务 .gz 文件
这是 Nginx 原生支持的预压缩机制,无需额外模块编译(只要含 http_gzip_static_module):
- 确认模块已就位:
nginx -V 2>&1 | grep -o with-http_gzip_static_module,有输出才可用 - 在具体服务静态文件的 location 块内启用,例如:
location ~* \.(js|css|html|svg|json)$ {<br> root /var/www/app;<br> gzip_static on;<br>} - 不写
gzip_types—— 它只认文件存在性,不管 MIME;也不在同一 location 写gzip on - 确保源文件(如
app.js)与压缩文件(app.js.gz)同目录、同名、时间戳一致(可用touch -r app.js app.js.gz同步)
启用 brotli_static always:服务 .br 文件
Brotli 预压缩需 HTTPS + Brotli 模块支持,且与 gzip_static 互斥,不能共存于同一 location:
- 先验证模块:
nginx -V 2>&1 | grep -o ngx_brotli,无输出则配置无效 -
brotli_static always;必须放在http{}或server{}顶层,不能放在 location 内 - 构建时生成
.br文件,例如:find ./dist -name "*.js" -exec brotli -q 6 -k {} \;(-k保留时间戳) - 必须关闭
gzip_static和gzip on(或至少设gzip off),否则可能因协商逻辑冲突导致降级失败
构建阶段必须同步产出压缩文件
预压缩机制的前提是文件存在。前端构建工具要主动打双版本:
- Webpack:用
compression-webpack-plugin,设algorithm: 'gzip'或'brotliCompress',deleteOriginalAssets: false - Vite:用
vite-plugin-compression,指定ext: '.gz'或'.br',并用filter排除图片/字体等二进制格式 - 已有部署补救:批量生成
.gz:find /usr/share/nginx/html -name "*.js" -exec gzip -c9 {} \; -exec mv {}.gz {}\.gz \;
兜底与验证要点
预压缩不是万能的,必须搭配合理兜底和验证手段:
- 保留
gzip on(全局 http 块)作为 fallback:应对漏压文件、动态接口或旧资源 - 用
curl -H "Accept-Encoding: gzip" -I https://site.com/main.js检查是否返回Content-Encoding: gzip - HTTPS 环境下测 Brotli:
curl -H "Accept-Encoding: br" -I https://site.com/main.js,应返回br且状态码 200 - 浏览器 Network 面板中对比 “Size”(传输大小)与 “Content”(原始大小),差值明显即生效











