目录
1.前言
2.关于gzip压缩
3.开启压缩配置
3.1 Vue中开启gzip压缩
3.2 tomcat中开启gzip压缩
3.3 nginx开启gzip压缩
3.4 node服务器
参考文献
1.前言
vue项目对应的单页应用在打包的时候,如果引入的第三方组件较多,会造成打包的生成的文件太大,一般情况下针对这种问题,比较常用的一种方法就是懒加载,配置路由的懒加载,只有在进入路由的时候才会加载对应的资源,在一定程度上优化了访问速度,但是不会降低打包后项目的大小,而且有很多小文件。在我看来最主要的一个问题在于懒加载失去了单页应用的亮点,使得应用和非单页应用一样,即:每次页面切换时候除了数据请求外还要对资源进行请求和加载。非懒加载的单页应用,首次加载成功后,后面所有的页面切换和跳转,基本就像是div的切换一样,剩下的主要就是数据的请求和渲染,但是懒加载会让这种优势丢失。
除了懒加载,另外一种比较好的方案就是开启gzip。这个在npm run build查看报告的时候也能看到通过gzip压缩有的js文件预估大小与实际大小有很大的差距。
2.关于gzip压缩
需要说明的是,Gzip压缩和前端没有一点关系,压缩操作是web中间件(tomcat/nginx/node...)做的,解压渲染操作是浏览器做的。对于前端开发而言,不需要做任何调整。
可能有同学就说了,vue开发的时候,在config/index.js中,通过productionGzip:true可以配置是否开启压缩的功能。怎么能说和前端开发没关系呢?
这里需要说明以下几点:
(1)前端在config/index.js中开启压缩,在打包的时候会自动把js/css进行压缩生成对应的.gz文件,如下图:
(2)假设使用nginx或者tomcat作为静态资源的web中间件,这些gz对于服务没有任何意义。web中间件想开启压缩,必须进行相关配置才行,web中间件开启压缩之后,是web中间件直接对相关js/css进行压缩,而不是直接使用压缩后的gz文件。这就意味着如果文件较大或者较多,而且请求量大的时候,对服务器的资源消耗很大,压缩是比较消耗cpu的。
(3)针对上述第二种情况,也可以通过自己编写Filter过滤器,在web.xml中配置后来实现直接使用gz压缩文件,省去tomcat中间件压缩的工作,从而降低服务器资源的消耗,具体参考这里。
综上:gzip压缩功能主要是后端web中间件的配合,和前端没有太多关系,vue-cli脚手架本身提供的有直接压缩为gz压缩包的功能,但是这个gz压缩包没用具体的作用,除非采用第三种情况,后端写了Filter自行处理压缩的时候才需要前端直接给gz文件。这也就意味着早几年非vue单页应用的html/js开发,也可以通过直接设置web中间件的方式实现资源压缩,提供网站的性能。
3.开启压缩配置
3.1 Vue中开启gzip压缩
打开config/index.js,修改如下配置:
其中也有英文注释,如果要开启gzip压缩,记得提前安装compression-webpack-plugin,即:
npm install --save-dev compression-webpack-plugin
在build/webpack.prod.conf.js中,如下:
(这块代码不用调整,是本来就有存在的)如果我们开启压缩,上面代码已经默认处理gzip压缩了,在build打包的时候,会一并生成gz压缩文件。注:假设后端不自己写filter,这里开不开压缩没什么关系,因为打包后的前端资源文件的压缩是web中间件做的,见上面3中说的。
划重点
默认npm install 安装的compression-webpack-plugin可能是最新版的,例如:我使用的时候默认安装的就是3.0.0,这时候会有问题,在使用npm run build打包的时候会报错如下;
网上有人说修改webpack.prod.conf.js中上面截图的asses为filename,我尝试了,不管用。
可行的解决方法:
修改package.json中compression-webpack-plugin的版本号,修改版本号为1.1.11,然后重新cnpm install以下就行了。
"compression-webpack-plugin": "^1.1.11",
3.2 tomcat中开启gzip压缩
我使用的tomcat版本是8.5,在tomcat/conf/server.xml中,找到如下:
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改为:
<Connector port="8181" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
useSendfile="false"
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/javascript,text/json"/>
- compression="on" 开启压缩功能
- compressionMinSize="50" 启用压缩的输出内容大小,这里面默认为2KB
- noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩
- compressableMimeType="text/html,text/xml,text/css,text/plain,application/javascript" 压缩的资源类型,这里有其他项压缩的可以用浏览器看,就是资源的ContentType
划重点
注意上面的配置,userSendfile=“false”一定不要忘记设置,不然压缩无效。
注意:tomcat7以后,js文件的mimetype类型变为了application/javascript,而在tomcat7以下则为text/javascript;具体的tomcat7定义的类型可以在:conf/web.xml文件中找到。
可以在web.xml下搜索,如我搜索javascript会找到如下代码:
<mime-mapping>
<extension>js</extension>
<mime-type>application/javascript</mime-type>
</mime-mapping>
3.3 nginx开启gzip压缩
找到nginx.config,调整如下:
http {gzip on; #开启或关闭gzip on off
gzip_disable "msie6"; #不使用gzip IE6
gzip_min_length 100k; #gzip压缩最小文件大小,超出进行压缩(自行调节)
gzip_buffers 4 16k; #buffer 不用修改
gzip_comp_level 3; #压缩级别:1-10,数字越大压缩的越好,时间也越长
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 压缩文件类型
gzip_vary off; #跟Squid等缓存服务有关,on的话会在Header里增加 "Vary: Accept-Encoding"
}
gzip使用环境:http,server,location,if(x),一般把它定义在nginx.conf的http{…..}之间
- gzip on
on为启用,off为关闭- gzip_min_length 1k
设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。默认值是0,不管页面多大都压缩。建议设置成大于1k的字节数,小于1k可能会越压越大。- gzip_buffers 4 16k
获取多少内存用于缓存压缩结果,‘4 16k’表示以16k*4为单位获得- gzip_comp_level 5
gzip压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值;- gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php
对特定的MIME类型生效,其中'text/html’被系统强制启用- gzip_http_version 1.1
识别http协议的版本,早起浏览器可能不支持gzip自解压,用户会看到乱码- gzip_vary on
启用应答头"Vary: Accept-Encoding"- gzip_proxied off
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_modefied(启用压缩,header头中不包含"Last-Modified"),no_etag(启用压缩,如果header头中不包含"Etag"头信息),auth(启用压缩,如果header头中包含"Authorization"头信息)- gzip_disable msie6
(IE5.5和IE6 SP1使用msie6参数来禁止gzip压缩 )指定哪些不需要gzip压缩的浏览器(将和User-Agents进行匹配),依赖于PCRE库以上代码可以插入到 http {...}整个服务器的配置里,也可以插入到虚拟主机的 server {...}或者下面的location模块内
3.4 node服务器
只要加上compress模块即可,代码如下:
var compression = require('compression')
var app = express();
//尽量在其他中间件前使用compression
app.use(compression());// 这是基本用法,如果还要对请求进行过滤的话,还要加上app.use(compression({filter: shouldCompress}))
function shouldCompress (req, res) {
if (req.headers['x-no-compression']) {
// 这里就过滤掉了请求头包含'x-no-compression'
return false
}
return compression.filter(req, res)
}
参考文献
【1】 Tomcat 开启Gzip压缩
【2】vue-cli 启动gzip压缩,及后台配置
【3】Tomcat7启用gzip压缩