预压缩文件(.gz/.br)需构建输出、部署结构与Nginx模块协同:先生成同名同路径的.gz/.br文件,再确保Nginx启用gzip_static/brotli_static、编译含对应模块,并保留原始文件以支持fallback。

预压缩文件(.gz 和 .br)不是“配个 Nginx 就能用”的功能,它依赖前端构建输出、文件部署结构和 Nginx 模块三者协同。核心在于:先有压缩文件,再让 Nginx 找得到、判得准、发得对。
构建阶段:让打包工具产出 .gz 文件
React/Vue 等 SPA 项目默认不生成 .gz,必须显式引入压缩插件:
- Webpack 项目:用 compression-webpack-plugin(v9+ 支持 Webpack 5),关键配置项包括:
• test:匹配 .js/.css/.html/.svg 等文本类资源
• threshold:建议设为 10240(10KB),避免小文件压缩反而变大
• deleteOriginalAssets: false:必须保留原始文件,.gz 只是“备用副本” - Vite 项目:推荐使用 vite-plugin-compression,行为一致,同样需保留源文件
- 构建后目录应呈现为:
build/static/js/main.x1y2z3.js
build/static/js/main.x1y2z3.js.gz
——两者同名同路径,缺一不可
Nginx 配置:启用预压缩并兼容 fallback
仅开启 gzip_static on 不够,需配合基础 gzip 和 Brotli 共存策略:
-
gzip_static on:Nginx 会优先查找同名 .gz 文件;找不到才走实时 gzip 压缩(所以
gzip on仍需开启) -
brotli_static on:同理,需提前生成 .br 文件;浏览器自动按
Accept-Encoding头选择 .br 或 .gz - 关键细节:
•gzip_types对gzip_static无效——只要文件存在 .gz,Nginx 就发它,不管 MIME 类型
• 必须确保 Nginx 编译时含--with-http_gzip_static_module和--with-http_brotli_module(后者需额外编译)
• HTTPS 是 Brotli 的硬性前提,HTTP 下浏览器通常忽略 .br
自动化脚本:补位未覆盖的构建场景
当无法修改构建流程(如 legacy 项目、CI/CD 权限受限),可用脚本在部署后自动补全压缩文件:
- Shell 脚本示例(部署后执行):
find ./dist -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) -exec gzip -k -9 {} \;
-k 保留原文件,-9 用最高压缩率(适合静态资源) - 注意时间戳一致性:若源文件更新但 .gz 未更新,Nginx 仍会发旧压缩包;脚本中可加入
stat判断是否需要重压 - 生产环境建议加日志与 dry-run 模式,避免误删或覆盖
验证与排查要点
上线后务必验证是否真正生效,常见陷阱:
- 用
curl -H "Accept-Encoding: gzip" -I https://yoursite.com/static/main.js查看响应头:
• 若返回Content-Encoding: gzip且Content-Length明显变小 → 成功
• 若返回 200 但无Content-Encoding→ .gz 文件缺失或路径不匹配 - 检查 Nginx error log:常见报错如
gzip_static: file not found,说明路径或权限问题 - 浏览器 DevTools → Network → 查看单个 JS/CSS 请求的 Size 列:对比 “transferred” 与 “resource” 大小,差值即压缩收益











