Nginx 开启 Gzip 压缩,为什么 JS 文件能缩小三分之二?
上一篇文章我们讲了为什么 Vue3 项目第一次打开会比较慢。
如果你打开浏览器的 Network 面板,会发现真正占用下载时间的,通常都是:
- JavaScript
- CSS
- HTML
- JSON
尤其是打包后的 JavaScript,一个文件甚至可能达到几百 KB,甚至几 MB。
那么有没有一种办法:
不用修改代码,就能让浏览器下载的数据变少?
答案就是:
Gzip 压缩。
几乎所有 Web 项目上线之后,都会开启 Gzip,它也是最基础、收益最高的性能优化手段之一。
一、什么是 Gzip?
Gzip 是一种数据压缩算法。
它不会改变文件内容,只会:
把文本数据压缩后再进行网络传输。
例如:
原来的 JavaScript:
app.js
900 KB
开启 Gzip 后:
app.js
↓
gzip
↓
300 KB
浏览器真正下载的,其实只有:
300 KB
下载完成以后,再自动解压成:
900 KB
整个过程用户完全感觉不到。
二、浏览器访问到底发生了什么?
假设没有开启 Gzip。
浏览器请求:
GET app.js
服务器直接返回:
900 KB
整个流程:
浏览器
│
GET app.js
│
▼
Nginx
│
▼
900KB
│
▼
浏览器
如果网络带宽比较低,下载时间自然就会变长。
开启 Gzip 后:
浏览器请求:
GET app.js
但是:
服务器先进行压缩:
900 KB
↓
gzip
↓
300 KB
然后返回:
300 KB
浏览器收到以后:
300 KB
↓
自动解压
↓
900 KB
整个流程如下:
浏览器
│
GET app.js
│
▼
Nginx
│
gzip
▼
300KB
│
网络传输
▼
浏览器
│
自动解压
▼
900KB 原始内容
整个过程浏览器自动完成。
开发者几乎不用写任何代码。
三、为什么 Gzip 压缩效果这么好?
因为:
JavaScript、CSS、HTML 都属于:
文本文件。
例如 JavaScript 中:
function
const
return
import
export
这些关键字会重复出现很多次。
CSS 中:
margin
padding
display
color
也会不断重复。
Gzip 的压缩原理就是:
找到重复的数据,只保存一份。
所以:
原来:
900 KB
压缩后可能变成:
300 KB
甚至:
250 KB
压缩率通常可以达到:
60% ~ 80%
具体效果与文件内容有关。(nginx.org )
四、是不是所有文件都适合 Gzip?
不是。
很多同学第一次接触 Gzip 时都会问:
图片能不能压缩?
答案是:
一般不建议。
例如:
jpg
png
webp
gif
mp4
这些文件本身就已经使用专门的压缩算法处理过了。
例如:
JPEG:
已经压缩
PNG:
已经压缩
WebP:
已经压缩
如果再进行一次 Gzip:
图片
↓
再次 gzip
通常:
- 文件不会明显变小;
- 服务器还需要额外进行压缩计算。
甚至有时候:
压缩后
反而更大
所以:
Gzip 最适合:
HTML
CSS
JavaScript
JSON
XML
SVG
而不是图片、视频等已经压缩过的二进制资源。(docs.nginx.com )
五、Nginx 如何开启 Gzip?
Nginx 已经内置了 Gzip 模块。
一般只需要修改:
nginx.conf
添加:
gzip on;
gzip_min_length 1k;
gzip_buffers 32 4k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types
text/plain
text/css
application/javascript
application/json
application/xml
text/javascript;
gzip_vary on;
其中:
开启:
gzip on;
表示:
启用 Gzip。
最小压缩大小:
gzip_min_length 1k;
表示:
小于:
1 KB
的文件不压缩。
因为:
压缩本身也需要时间。
文件太小意义并不大。
压缩等级:
gzip_comp_level 6;
可以设置:
1 ~ 9
数字越大:
压缩率越高。
但是:
CPU 消耗也越高。
生产环境通常:
5
或者
6
已经足够。
官方同样提供了这些配置项的详细说明。(nginx.org )
六、浏览器为什么知道要解压?
很多人会疑惑:
服务器发送的是:
300 KB
浏览器为什么知道它其实是压缩文件?
因为:
HTTP 响应头里面会告诉浏览器:
Content-Encoding: gzip
浏览器看到:
gzip
以后:
会自动完成:
解压
↓
解析
↓
执行
所以:
开发者根本不需要手动处理。
七、怎么验证是否开启成功?
打开浏览器:
F12
↓
Network
刷新页面。
点击任意一个:
app.js
查看:
Response Headers
如果出现:
Content-Encoding: gzip
说明:
Gzip 已经生效。
很多浏览器还会同时显示:
Transferred
300 KB
以及:
Resource Size
900 KB
说明:
网络真正传输的是:
300 KB
浏览器解压以后:
得到:
900 KB
八、开启 Gzip 后是不是就结束了?
其实还没有。
很多人以为:
开启 Gzip
↓
性能优化完成
实际上:
Nginx 每次收到请求时,都需要:
读取 JS
↓
实时压缩
↓
发送
如果网站访问量越来越大:
100 人
1000 人
10000 人
服务器就需要不停进行:
gzip
gzip
gzip
虽然 Nginx 的效率已经很高,但仍然会消耗一定的 CPU 资源。(docs.nginx.com )
因此:
很多生产环境都会进一步采用:
预压缩(Pre Compression)
也就是:
在打包阶段就提前生成:
app.js.gz
服务器直接返回已经压好的文件。
这样就不需要每一次请求都实时压缩。
这也是下一篇文章要介绍的内容。
九、总结
Gzip 是 Web 性能优化中最基础、收益最高的一项优化。
它通过压缩文本资源,减少网络传输的数据量,从而提升页面加载速度。
它特别适合:
- HTML
- CSS
- JavaScript
- JSON
- XML
- SVG
而对于图片、视频等已经压缩过的资源,则通常不建议再次进行 Gzip。
对于大多数 Vue、React 项目来说,只需要开启 Nginx 的 Gzip,就能明显减少静态资源的传输体积。
当然,Gzip 并不是终点。
如果希望进一步降低服务器 CPU 开销,生产环境通常还会采用**预压缩(gzip_static)**的方式。
下一篇文章,我们就来聊聊:
为什么生产环境更推荐 Vite 预压缩 + Nginx gzip_static,而不是每次都让 Nginx 实时压缩。