Nginx默认不压缩HTML,因其gzip_types仅含text/plain,必须显式添加text/html才生效;漏配或被location覆盖是90%失败主因,需验证Content-Encoding: gzip及开启gzip_vary on。

HTML 能且必须做 gzip 压缩,但光写 gzip on 不等于生效——90% 的配置失败,都卡在 text/html 没被明确列入 gzip_types,或被 location 块意外覆盖。
为什么 Nginx 默认不压 HTML?
Nginx 的 gzip_types 默认只包含 text/plain,其他 MIME 类型(包括 text/html)必须显式声明,否则即使 gzip on 也完全不压缩 HTML。这不是 bug,是设计上的保守策略。
- 常见错误:只配了
gzip on和gzip_min_length,漏掉gzip_types或写成gzip_types *(Nginx 不支持通配符) - 验证方法:用
curl -H "Accept-Encoding: gzip" -I https://yoursite.com/index.html,若响应头无Content-Encoding: gzip,基本可断定text/html未命中 -
gzip_vary on必须开启,否则 CDN 或反向代理可能缓存未压缩版本,导致部分用户看到大体积 HTML
Apache 下 .htaccess 的安全写法
Apache 依赖 mod_deflate(不是已废弃的 mod_gzip),且必须用 AddOutputFilterByType 绑定 MIME 类型,仅靠文件后缀(如 .html)不可靠——比如 PHP 输出的 HTML 页面就可能被跳过。
- 必须包含:
AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json - 避免写
SetOutputFilter DEFLATE在目录级(.htaccess)而不限定类型,否则可能误压图片或字体文件 - 检查是否启用模块:
a2enmod deflate后需重启 Apache;若用 cPanel 或共享主机,部分环境禁用mod_deflate,得换用 PHP 层压缩(如ob_gzhandler)
Node.js(Express)中 compression 中间件的坑
compression() 默认只压缩 text/ 开头和部分 JSON/JS 类型,但 Express 的 res.send() 发送 HTML 时默认设的是 text/html; charset=utf-8,所以通常能覆盖。问题多出在自定义响应头或流式响应场景。
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
立即学习“前端免费学习笔记(深入)”;
- 若用
res.writeHead(200, { 'Content-Type': 'text/html' })手动设头,确保没覆盖charset,否则某些旧版中间件可能拒绝压缩 - 不要在
compression()之后再挂载express.static()——顺序错会导致静态 HTML 文件绕过压缩 - 开发环境建议加
threshold: 1024(默认 1KB),避免小片段 HTML 白耗 CPU;生产环境可保留默认
预压缩(.gz 文件)比实时压缩更稳
对纯静态 HTML(如 Jekyll、VuePress 输出),直接生成 index.html.gz 并启用 gzip_static on,能彻底规避运行时 CPU 波动和 MIME 类型匹配问题。
- 生成命令:
gzip -k -f -6 index.html(-6级足够,-9几乎不增益还拖慢构建) - Nginx 配置中,
gzip_static on必须与gzip on同级(都在http或server块),不能放在location内 - 关键细节:修改 HTML 后必须同步重生成 .gz 文件,否则 Nginx 会 fallback 到未压缩原始文件,且不报错
最常被忽略的其实是 CDN 层——Cloudflare、阿里云全站加速等默认不继承源站 gzip 设置,必须单独打开「Brotli」或「Gzip 压缩」开关,否则你在 Nginx 里调得再细也没用。


















