Nginx 开 Gzip 加浏览器缓存,首屏加载快一倍
一、背景:静态站点首屏太慢
把一个以 JS、CSS 为主的静态站扔到 Nginx 上,首屏要两三秒。看网络面板,几个 js 文件几百 KB 没压缩,重复访问还在重新下载。两件事就能解决:开 Gzip 把文本压下去,给静态资源加浏览器缓存让二次访问直接读本地。都不用动业务代码,纯配置,改完首屏明显变快。我第一次配的时候首屏从 2.8 秒降到 1.3 秒左右,肉眼都能感觉到。关键在于这两招零成本、可逆、随时能回退,不像改架构那么重,下午配完下午就能见效。
二、核心操作:Gzip 与缓存配置
在 Nginx 的 http 或 server 块里加上:
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
gzip_comp_level 6;
location ~* \.(js|css|png|jpg|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
gzip on 开启压缩,gzip_types 指定对哪些类型压(文本类收益高),gzip_min_length 拦掉太小的文件免得压了反而亏,comp_level 6 是速度与压缩比的甜点。下面的 location 给静态资源加 30 天过期,配合 immutable 告诉浏览器放心缓存。改完先校验再生效:
nginx -t && nginx -s reload
nginx -t 只检查语法不生效,确认无误再 reload,避免直接 restart 打断已有连接。再用 curl -I 验证响应头:
curl -I http://localhost/app.js
# 看有没有 Content-Encoding: gzip 和 Cache-Control: max-age=2592000
请求链路是:

三、原理拆解:为什么能提速
Gzip 在传输前把文本压小,浏览器收到再解压,js/css 通常能小 70%。浏览器缓存则是响应头里带 Expires 或 Cache-Control,二次访问浏览器直接用本地副本,连请求都省了。如果本地副本过期,浏览器会带 If-None-Match 或 If-Modified-Since 来问,服务端比对后返回 304 表示没变,仍然不传正文。两者针对不同阶段:Gzip 省每次传输的字节,缓存省掉重复请求。文件更新时靠文件名带 hash(内容寻址)让旧缓存失效,避免用户一直拿旧版。若编译环境支持,还可以开 brotli 替代 gzip,压缩率通常更高,但要注意 Nginx 需编译时带 ngx_brotli 模块。还有两个细节值得补:gzip_vary on 让 Nginx 在响应里加 Vary: Accept-Encoding,避免中间代理把压缩版发给不支持解压的客户端;老浏览器(如 IE6)对压缩支持有坑,可用 gzip_disable “msie6” 直接跳过。这两项默认不写也能跑,但上了 CDN 或反向代理后加上更稳。
四、踩坑记录
- gzip_types 把图片、pdf 也列进去。这类本来就是压缩格式,再压反而更慢、体积还略涨,只压文本类。
- 缓存 30 天但文件更新用户拿旧版。文件名带内容 hash,或加版本号,别靠手工清缓存。
- gzip_comp_level 设 9。压到极致吃 CPU,性价比低,6 左右最划算。
- 没开 sendfile。大文件用 sendfile on 走零拷贝,传输效率更高。
- 反向代理后端响应已带 Content-Encoding 又再压。确认上游没压过,否则重复压缩甚至乱码。
- 改完配置没校验直接 reload。语法写错 reload 会失败甚至回退,先用 nginx -t 跑通再 reload 才稳。
五、总结
静态站点提速,Nginx 的 Gzip 加浏览器缓存是性价比最高的两招,纯配置、零代码。记住文本才压、文件要带 hash、压缩级别取平衡、改前先 nginx -t,命中缓存后首屏能快一大截。配完用 curl -I 实测一遍响应头,比凭感觉靠谱。
- 点赞
- 收藏
- 关注作者
评论(0)