一、 问题背景
最近发现Vue打包chunk-vendors.js文件过大,页面加载有点慢。为了减少加载时间,提升用户体验,因此打包时我们使用了gzip压缩(需要服务端配合修改nginx配置)。
二、为什么要用Gzip压缩?
-
主流浏览器都支持
Gzip压缩,只有极少数的手机轻量浏览器可能不支持。 -
压缩效果好,使用
Gzip压缩后文件大小能减少60%-70%左右。
三、 Gzip工作原理
- 浏览器请求
url,并在请求头重设置属性accept-encoding:gzip。表明浏览器支持gzip,这个参数是浏览器自动会携带的请求头信息。 - 服务器收到浏览器发送的请求之后,服务器会返回压缩后的文件,并在响应头中包含
content-encoding:gzip;如果没有压缩文件,服务器会返回未压缩的请求文件。 - 浏览器接收到服务器的响应,根据
content-encoding:gzip响应头使用gzip策略去解压压缩后的资源,通过content-type内容类型决定怎么编码读取该文件的内容。
四、Gzip压缩的几种方案
1. Nginx实时压缩
浏览器请求资源时,Nginx服务器对文件进行gzip压缩后返回给浏览器。前端不用做任何修改正常打包,但这样会消耗服务器性能。
Nginx开启gzip压缩,代码如下:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
client_max_body_size 100m;
#keepalive_timeout 0;
keepalive_timeout 120;
# 开启gzip
gzip on;
# 设置缓冲区大小
gzip_buffers 4 16k;
#压缩级别官网建议是6
gzip_comp_level 6;
#压缩的类型
gzip_types text/plain application/javascript text/css application/xml text/javascript application/x-httpd-php;
#允许压缩的文件最小字节
gzip_min_length 10k;
server {
listen 80;
}
}}
| 指令 | 格式 | 说明 |
|---|---|---|
gzip | gzip on | off | 控制是否开启gzip,默认开启 |
gzip_min_length | gzip_min_length length | 大于length的响应才压缩,默认为20字节 |
gzip_http_version | gzip_http_version 1.0 | 1.1 | 对1.1的请求开启压缩功能 |
gzip_buffers | gzip_buffers number size | 设置gzip申请内存的大小,申请number个大小为size的空间 |
gzip_comp_level | gzip_comp_level_ level | 设置压缩等级,1-9,1表示压缩程度最低,压缩率最高。9表示相反,最费时间。 |
gzip_types | gzip_types mine-types | 根据mine-type类型进行压缩,可以取值text/plain等。 |
nginx配置里的gzip属性和gzip_static 属性可以同时设置为on,gzip_static的优先级高,如果存在.gz静态资源会优先时候静态资源返回,若不存在,会实时生成压缩文件。
如何区分使用了静态加载还是在线压缩?
响应头的Content-Edcoding:gzip表示gzip压缩已经生效,而Etag中只有简单字符表示静态资源加载,而前面带 W/表示启动了在线压缩。
2. webpack配置(前端打包压缩)
打包时通过webpack配置生成的对应的.gz文件,浏览器请求文件后会自动解压为js或者css等资源文件。打包借助compression-webpack-plugin插件打包出.gz文件。
安装插件:
npm install compression-webpack-plugin—save-dev
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
const CompressionPlugin = require("compression-webpack-plugin"); // 开启gzip压缩, 按需引用
module.exports = defineConfig({
configureWebpack: {
plugins: [
new CompressionPlugin({
algorithm: 'gzip', // 使用gzip压缩
test: /.js$|.html$|.css$/, // 匹配文件名
filename: '[path][base].gz[query]', // 压缩后的文件名(保持原文件名,后缀加.gz)
minRatio: 1, // 压缩率小于1才会压缩
threshold: 10240, // 对超过10k的数据压缩
deleteOriginalAssets: false, // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
}),
]
}
})
可以通过配置deleteOriginalAssets:true,删除未打包资源,但推荐保留未打包资源
此时Nginx服务器只需要配置:gzip_static on
3. Nodejs启用gzip
nodejs启用gzip相对来说比较简单,以express框架为例如何启用gzip;
npm install compression
npm install @types/compression --save-dev
import compression from 'compression'
...
const app = express();
// 尽量在其他中间件前面
app.use(compression({level:5}));
...
参考文章 ☞ 前端性能之gzip压缩