静态资源合并压缩Nginx配置大幅节省带宽
为什么需要合并压缩静态资源
当你的网站 CSS、JS、图片越堆越多,用户每次访问都要发起几十个 HTTP 请求,传输大量未压缩的文件,带宽和加载时间都会暴涨。Nginx 合并与压缩 可以在不改动前端代码的前提下,把多个小文件合并成一个、启用 Gzip 压缩、设置长效缓存,直接减少请求数和体积。
本文面向新手,从零开始一步步配置。
前置准备
- 一台安装了 Nginx 的服务器(系统不限,命令以 CentOS/Ubuntu 为例)
- 已拥有站点配置文件(通常在
/etc/nginx/conf.d/或/etc/nginx/sites-available/) - 能通过 SSH 或面板(如宝塔)编辑配置,并重启 Nginx 使生效
分步操作:Nginx 合并压缩与缓存配置
1. 合并 CSS/JS 文件(use concat module)
Nginx 官方提供了 concat 模块(第三方,需编译或从包管理器安装),它可以自动把多个请求合并成一个。
- 检查是否已有模块:
nginx -V 2>&1 | grep concat,如果输出含ngx_http_concat_module则跳过安装。 - 安装步骤(以编译方式举例):
# 下载模块源码
wget https://github.com/alibaba/ngx_http_concat_module/archive/master.zip
unzip master.zip
# 查看当前 nginx 编译参数
nginx -V
# 在编译参数后加上 --add-module=/path/to/ngx_http_concat_module-master
./configure --with-cc-opt='...' --with-ld-opt='...' --add-module=/path/to/ngx_http_concat_module-master
make && make install
如果觉得麻烦,也可以手动在构建阶段合并不使用模块(文中会提供另一种做法)。
- 在 server 块中启用合并(路径示例
/static/):
location /static/ {
concat on;
concat_types application/javascript text/css;
concat_unique on;
}
配置后,前端引用时用 ? 拼接文件:
?/static/? 即可合并。
?a.js,b.js
免模块替代方案:在 Nginx 配置中用 sub_filter 或直接在项目构建时将多个 JS/CSS 手动合并为一个文件。
本文推荐前者更省事。
2. 启用 Gzip 压缩(配置 nginx.conf)
Gzip 是减少传输体积最直接的方法,大约能压缩 60%-80%。
http {
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_vary on;
gzip_disable "msie6";
}
gzip_min_length 1k:小于1KB的文件不压缩,避免浪费CPU。gzip_comp_level:1-9,推荐5,平衡大小与性能。- 重启 Nginx:
nginx -s reload
3. 设置浏览器缓存过期时间
给静态资源加上 Expires 或 Cache-Control,让用户重复访问时不请求服务器。
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
expires 30d:30天不请求服务器。immutable:告诉浏览器文件永不改变(适合带上版本号的资源)。
4. 配置 ETag 和 Last-Modified(可选)
Nginx 默认开启 ETag,无需额外配置。
若想关闭或自定义:
location ~* \.(css|js)$ {
etag on;
if_modified_since exact;
}
这能让浏览器校验缓存是否过期,节省带宽。
常见问题与避坑指南
Q:合并文件后部分资源加载失败?
A:检查 concat 的路径是否正确,确保所有文件在同一个 location 目录下,且相对路径必须以 / 开头。
Q:Gzip 压缩后浏览器显示乱码?
A:确认配置文件没有添加额外的 charset 覆盖。建议在 http 块设置 charset utf-8;
Q:修改配置后测试网站变慢?
A:可能是 gzip_comp_level 过高,适当降低到 3-4。同时检查 gzip_min_length 是否太小,大量小文件压缩反而增加CPU开销。
Q:合并后的缓存更新怎么办?
A:建议在文件名中加入版本号,并修改 concat 拼接路径。例如 /static/??v=2&a.js,b.js,或直接修改文件哈希。
避坑总结:
- 修改配置前备份原文件。
- 每个 location 块不要重复开启 gzip,避免覆盖。
- 合并模块如果编译失败,退而求其次手动合并。
效果验证
- 浏览器开发者工具:按 F12 打开 Network,刷新页面。
- 观察请求个数是否减少(合并后多个文件变一个)。
- 查看单个响应头中
Content-Encoding: gzip,确认压缩成功。 - 查看
Cache-Control和Expires是否符合设定。
- 在线工具测试:用 GTmetrix 或 PageSpeed Insights 对比前后体积和请求数。
- 带宽比较:查看服务器带宽监控饼图(如 iftop),配置生效后出向流量有明显下降。
如果一切正常,你的网站带宽消耗会降低 30%-60%,首屏加载速度提升明显。
若中途遇到错误,先检查 Nginx 错误日志:tail -f /var/log/nginx/error.log,一般都有明确提示。
结语
本文从合并、压缩、缓存三个角度给出了可直接执行的 Nginx 配置,零基础用户按步骤操作即可生效。
建议先在一台测试机器上验证,确认无误再推生产环境。
如果你正在优化带宽资源,这套配置几乎能立竿见影地减少流量开销。
如遇到其他奇怪现象,欢迎留言讨论。