gzip的两种实现方式。

1、动态gzip压缩的实现。

当前端Vue使用普通的编译打包的方式构建出index.html,xxx.js,xxx.css等文件后,可以直接放到nginx的虚拟主机根目录下即可通过绑定的域名去访问。这时如果想开启gzip压缩则按照如下示例:

gzip on; # 打开gzip
gzip_buffers 16 8k; # 缓冲区数量和大小 (按照内存页大小以8K为单位申请16倍的内存空间)
gzip_comp_level 6; # 压缩级别1-9级别越大越吃性能,压缩比越高,视实际配置设置
gzip_http_version 1.1; # 用于识别http协议的版本,早期的浏览器不支持gzip压缩,用户会看到乱码,所以为了支持前期版本加了此选项。默认在http/1.0的协议下不开启gzip压缩。
gzip_min_length 256; # 最小触发值,以K为单位,当值为0时,所有页面都进行压缩。
gzip_proxied any; # Nginx做为反向代理的时候启用:off – 关闭所有的代理结果数据压缩;expired – 如果header中包含”Expires”头信息,启用压缩;no-cache – 如果header中包含”Cache-Control:no-cache”头信息,启用压缩;no-store – 如果header中包含”Cache-Control:no-store”头信息,启用压缩;private – 如果header中包含”Cache-Control:private”头信息,启用压缩;no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息,启用压缩;no_etag – 启用压缩,如果header中包含“ETag”头信息,启用压缩;auth – 启用压缩,如果header中包含“Authorization”头信息,启用压缩;any – 无条件压缩所有结果数据
gzip_vary on; # 增加响应头”Vary: Accept-Encoding”
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon; # 设置需要压缩的MIME类型,如果不在设置类型范围内的请求不进行压缩。推荐直接使用我这里定义的这些类型。
gzip_disable "MSIE [1-6]\.(?!.*SV1)"; # 通过表达式,表明哪些UA头不使用gzip压缩

配置完成之后,直接执行nginx -s reload 即可生效。
00f455cf0cd54bd384211ff658d22fbb.png
浏览器控制台把Content-Encoding显示打开即可查看到有gzip压缩在生效。


2、静态gzip压缩的实现

方法1中的动态压缩有一个缺点就是:客户端每次过来请求时服务端都需要进行压缩,而每次都是来对这些静态资源进行压缩,就有点资源浪费的感觉。我们自然而然的就会想到能不能把这些静态资源提前压缩成gz包,这样就不需要服务端去重复做着相同的压缩指令。
当然了,这个需要前端人员的配合。

首先需要在前端安装压缩插件:compression-webpack-plugin然后在vue.config.js中增加如下配置

new CompressionPlugin({
test: /\.(js|css)(\?.*)?$/i, // 哪些文件要压缩
filename: '[path][base].gz[query]', // 压缩后的文件名
algorithm: 'gzip', // 使用gzip压缩
threshold: 10240, //超过10K的文件才会压缩
minRatio: 0.8, // 压缩率 取值要<1.0
deleteOriginalAssets: true // 删除未压缩的文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false
})

打包完之后同样的步骤上传到nginx的虚拟主机根目录,然后nginx需要一个有http_gzip_static_module模块【ps:这里推荐使用春哥的openresty,虽然我们不是巨人,但是我们要学会站在巨人的肩膀上】有了模块之后需要设置gzip_static on;才可以正常解析静态gz资源。
注:gzip_static on;可以设置到http、server或者location中。


3、反向代理到gz静态压缩资源的处理

有时候我们的前端资源并不是直接在最外层的web服务器中,大多数情况下都是最外层的web服务器反代到内网的某个服务上。例如下面这种简单的反代结构:

graph LR
Client((Client))
NGINX[网关NGINX]
backed[应用NGINX/TOMCAT等]
Client-->|访问|NGINX
NGINX-->|反代|backed

这时如果没有做额外处理的话gzip压缩的资源请求将会404,我们需要做以下处理即可解决该问题。

分析:因为静态压缩后实际的资源为gz包而非js等原文件,所以直接请求xxx.js将会报404。所以我们首先想到的应该是重写请求为gz。

rewrite ^(.*)$ /$1.gz break; # 使用rewrite将请求重写为.gz的请求

再分析:如上操作后,确实是能在【应用NGINX/TOMCAT等】定位到gz文件,但是还是无法解析该资源,所以我们要声明一下资源的Content-Encoding,这样内层的web服务器就能正确的解析到该资源。

add_header Content-Encoding gzip;

针对js和css反代静态压缩资源的完整配置如下:

location ~ .*\.(js|css)?$ {
rewrite ^(.*)$ /$1.gz break;
add_header Content-Encoding gzip;
proxy_pass http://10.0.10.35:9001;
include proxy.conf; # 这个是我定义的公共proxy header处理
expires 7d;
access_log off;
}