码上熊猫 · 技术干货
原创 2026年5月17日 · 发布于公众号
前端页面加载慢,很多人第一反应是:
是不是服务器太慢?是不是带宽不够?是不是前端包太大?
都有可能。
但有一个低成本配置,经常被忽略:
Nginx gzip 压缩。
它解决的问题很直接:
把 HTML、CSS、JS、JSON 这些文本资源压小,再传给浏览器。
同样一个 app.js,原来 800 KB。
开启 gzip 后,可能只传 200 KB 左右。
服务器没换,代码没改,用户下载的数据少了,页面自然更快。
这篇不先堆原理。
先给一份常用配置。
先给一份 gzip 配置模板
一般放在 http 块里:
http { gzip on; gzip_comp_level 5; gzip_min_length 1024; gzip_vary on; gzip_proxied any; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml application/rss+xml image/svg+xml; server { listen 80; server_name www.example.com; root /data/www/frontend; index index.html; location / { try_files $uri $uri/ /index.html; } }}如果你只是想快速启用,可以先用这份。
它覆盖了前端项目最常见的资源:
HTML、CSS、JS JSON、XML、SVG
不过,配置能复制,不代表可以闭眼复制。
下面把几个关键参数拆开讲清楚。
这几个参数最关键
1. gzip on
gzip on;开启 gzip 压缩。
没有这一行,后面写再多都没用。
就像买了跑鞋、运动服,最后没出门。装备挺齐,效果为零。
2. gzip_types
gzip_types text/plain text/css application/json application/javascript image/svg+xml;指定哪些响应类型需要压缩。
gzip 最适合压缩文本类内容:
不要把图片、视频塞进
gzip_types。压缩饼干再压一遍,不一定更小,但牙更疼。
3. gzip_min_length
gzip_min_length 1024;响应体小于 1024 字节时,不压缩。
小文件压缩收益不明显,压缩头加上去反而没省多少。
一般设置为 1k 或 1024 比较合适。
4. gzip_comp_level
gzip_comp_level 5;压缩级别,范围 1-9。级别越高,压得越小,但 CPU 消耗越高。
| 推荐 | ||
生产环境一般用 5。
这不是游戏画质设置,别一上来就拉满。
5. gzip_vary
gzip_vary on;开启后,响应头会带:
Vary: Accept-Encoding这对 CDN、代理缓存很重要。有的客户端支持 gzip,有的不支持,缓存层需要知道:同一个 URL,是否要按 Accept-Encoding 区分缓存。如果你前面有 CDN,这个建议打开。
怎么验证 gzip 是否生效?
不要只看配置文件,配完一定要测。
先检查配置并重载:
nginx -tnginx -s reload用 curl 请求一个 JS 或 CSS 文件:
curl -I -H "Accept-Encoding: gzip" http://www.example.com/static/app.js如果生效,响应头里应该能看到:
Content-Encoding: gzip也可以看资源大小变化:
# 开启 gzipcurl -H "Accept-Encoding: gzip" -o /dev/null -s -w "%{size_download}\n" http://www.example.com/static/app.js# 不带 gzipcurl -o /dev/null -s -w "%{size_download}\n" http://www.example.com/static/app.js如果开启 gzip 后下载体积明显变小,就说明有效。
我本地用 190 KB 左右的 app.js 实测:
响应头里也能看到:
Content-Encoding: gzipVary: Accept-Encoding浏览器里也可以验证:打开 Chrome DevTools → Network → 选择资源 → 看 Response Headers,重点找:
Content-Encoding: gzip配置文件不会自己发光,响应头才算证据。
另外,我测了一个只有 6 bytes 的 small.js,响应头里没有Content-Encoding: gzip。这是正常的,因为 gzip_min_length 1024 生效了。
常见坑:为什么我配了 gzip 还是没效果?
1. 请求没有带 Accept-Encoding
测试时一定要加:
curl -I -H "Accept-Encoding: gzip" http://www.example.com/app.js2. 文件太小
小于 gzip_min_length 的文件不会被压缩。不是 bug,是设计。
3. 类型没写进 gzip_types
比如接口返回 application/json,但配置里没写,JSON 就不会被压缩。
4. 图片、视频没变小
这是正常的。JPG、PNG、MP4 本身已压缩,gzip 对它们收益很低。
图片该压缩图片,视频该压缩视频,别让 gzip 干它不擅长的活。
5. 前面有 CDN
如果用了 CDN,要确认:
CDN 是否开启压缩 CDN 是否缓存了旧响应 响应头里有没有 Vary: Accept-Encoding
有时候不是 Nginx 没生效,是 CDN 在半路接管了。
gzip 和静态缓存要一起看
gzip:单次传输体积变小 静态缓存:减少请求次数,或直接走浏览器缓存
这两个不是二选一,是搭档。
前端静态资源建议一起配:
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?)$ { expires 7d; add_header Cache-Control "public";}完整示例:
gzip on;gzip_comp_level 5;gzip_min_length 1024;gzip_vary on;gzip_types text/plain text/css application/json application/javascript image/svg+xml;server { listen 80; server_name www.example.com; root /data/www/frontend; index index.html; location ~* \.(js|css|svg|woff2?)$ { expires 7d; add_header Cache-Control "public"; } location / { try_files $uri $uri/ /index.html; }}gzip 不是缓存,缓存也不是 gzip。一个负责压小,一个负责少请求。两个一起用,前端资源加载才更舒服。
生产环境建议怎么选?
application/json,验证响应头 | |
gzip_comp_level | |
Vary 响应头 | |
我一般这样配:
gzip on;gzip_comp_level 5;gzip_min_length 1024;gzip_vary on;gzip_proxied any;gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;先用这套跑起来,再根据 CPU、带宽、资源类型调整。
性能优化不是把参数拉满。而是让资源、CPU、带宽之间达到一个合适的平衡。
最后记住这句话
Nginx gzip 是前端性能优化里值得最先做的一项。
成本低,收益明显,配置也不复杂。
但它不是万能的:
gzip → 让文本资源变小 缓存 → 减少重复请求 CDN → 让资源离用户更近 图片压缩 → 处理大图
这几件事配合起来,页面加载才会真正变快。
所以别只问“gzip 开了吗?”还要问:
压了哪些类型? 压缩级别合不合适? 响应头怎么验证? 缓存有没有一起配? CDN 有没有接管?
能打开页面是第一步。让页面更快、更稳、更省带宽,才是生产环境该考虑的事。
如果你对 Nginx、Linux 排障、服务上线这类内容感兴趣,可以关注 码上熊猫。
后面会继续整理更多能直接复制、也讲清楚为什么这么配的生产配置模板。
你们线上有没有开 gzip?开启后前端资源体积大概降了多少?欢迎在评论区聊聊。
码上熊猫 · 让技术更有趣
夜雨聆风