本文讲的并不是什么新东西,但使用vue的开发人员都应该有所了解。
vue
给开发带来了很多的便利,但是如果不做任何优化,
vue
项目打包出来的文件往往很大,如果网络环境不好,打开页面看到的就会是无尽的加载中。
等了半分钟页面终于出现了。如果项目里面引入了一些比较大的组件,等待时间可能会更久。根本原因还是文件体积太大,导致网络响应时间长。
遇到这种情况首先我们先找到文件体积大的原因,借助 webpack-bundle-analyzer插件,我们可以直观看到打包后每个文件的内容和大小。
可以看到最大的文件达到了1.9M,打包时间146秒,页面加载时间也达到30多秒,这简直是无法忍受的。
既然我们知道了原因,就可以着手解决问题。万能的互联网上可以找到很多解决方法。
例如:
Gzip、cdn、splitChunk、图片压缩
等等,下面会挑几个
“
有意思
”
的方法聊聊。
gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。
目前主流的浏览器,Chrome、firefox、IE等都支持该协议。常见的服务器如Apache、Nginx、IIS同样支持gzip。要使用gzip功能:
l gzip_disable:(IE5.5和IE6 SP1使用msie6参数来禁止gzip压缩 )。指定哪些不需要gzip压缩的浏览器(将和User-Agents进行匹配)。
l gzip_vary:增加响应头”Vary: Accept-Encoding”。
l gzip_proxied:Nginx做为反向代理的时候启用:
· 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”头信息,启用压缩
l gzip_types:这个参数是指设置需要压缩的MIME类型,如果不在设置类型范围内的请求不进行压缩。
l gzip_comp_level:设置gzip压缩等级,等级越压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大。范围是1-9,根据需求设定。
l gzip_buffers:设置用于处理请求压缩的缓冲区数量和大小。比如32 4K表示按照内存页(one memory page)大小以4K为单位(即一个系统中内存页为4K),申请32倍的内存空间。建议此项不设置,使用默认值。
l gzip_http_version:用于识别http协议的版本,早期的浏览器不支持gzip压缩,用户会看到乱码,所以为了支持前期版本加了此选项。默认在http/1.0的协议下不开启gzip压缩。
首先安装compression-webpack-plugin插件
重新打包项目,再次访问页面我们可以看到在content-encoding一列出现了gzip,说明配置成功了,1.9M的文件压缩之后只有599k,压缩比例达到70%左右,页面
加载速
度有了质的飞跃,页面出现只用了3.32s。
当然,还有其他的压缩算法可以选择,例如Brotli,据说是比gzip压缩效果更好,感兴趣的读者可以试验一下。
我们可以将一些第三方组件通过cdn的方式引入,从而减小打包的文件数量,可以缩短打包时间和减小最后的文件体积。
下面我们将
vue
、
vuex
、
vue-router
、
element-ui
使用
cdn
引入。
其中属性名是引入的模块名,值是需要替换的变量,这个值必须和 cdn 中提供的一样,其作用是不打包使用外部引入的扩展,也就是 build 的时候不打包该模块。
可以看到打包出来的文件
明显小了
,chunk-vendors从1.9M减小到了1.14M。
打包时间为107秒,配合使用gzip页面加载时间为2.65秒,不过如果cdn链接失效会导致资源缺失。
在开发的时候,需要合理的划分各模块,做到首屏加载的时候只读取必要的模块,其他模块在需要的时候才从服务器加载。通过这种异步加载组件的方式,在打包的时候就不会把相关的组件打包到首屏相关的js中,可以减少首屏渲染相关文件的大小。
举个例子,一开始在代码中通过下面的方式引入“floatLabel”这个组件,这个组件引入了cytoscape.js和klay.js两个库,这意味着一开始它们都会被加载(可以参考CDN模块的打包结果)。
但是这个floatLabel组件在最开始是不会被使用到的,于是我们通过动态引入的方式引入它。
可以看到chunk-vendors已将减少到了178.64KB,打包时间也减少到了75秒,页面出现的时间变为了1.26s。
这个时候最大的文件已经变成了klay.js、cytoscape.js和jquery.js的这个chunk,如果看着不舒服想把他们拆开,可以用splitChunks将他们拆开,或者有cdn资源的话也可以通过cdn引入。
splitChunks字面意思就是
拆分chunks
,在vue.config.js中添加下面的配置。
可以看到刚才993K的文件被拆成了几个稍微小一点的包。
但是这么做对首屏加载影响不大,因为一开始都没有加载到这几个包。而且几个几百K的包和一个1M左右的包哪种方式比较好就需要进一步评估了。
总 结
上面提到的都是vue项目里面会常用到的一些webpack相关的优化,并不是说都用上了就是好的。大家需要根据项目的实际情况进行选择,没有绝对正确的优化方法,只有尝试过后才能找到最合适的打包方式。
当然还有很多别的方案没有提及,比如DllPlugin、图片压缩、Happypack等,感兴趣的朋友们可以多尝试、多比对,合适的打包方案总是要经过大量的实验得出来的。最后再推荐TerserPlugin(可以屏蔽输出)和ProgressBarPlugin(记录打包时间)两个插件,个人感觉挺好用的,其实webpack还有很多好用的插件,大家可以多多挖掘。
注:上面的页面加载时间也会受到网速的影响,仅供参考。
想学习更多技术内容
别忘了关注普适极客