vlambda博客
学习文章列表

技术13期:vue项目的webpack打包优化【前端篇】


前言


 本文讲的并不是什么新东西,但使用vue的开发人员都应该有所了解。 
vue 给开发带来了很多的便利,但是如果不做任何优化, vue 项目打包出来的文件往往很大,如果网络环境不好,打开页面看到的就会是无尽的加载中。
“what ???是我断网了吗?
等了半分钟页面终于出现了。如果项目里面引入了一些比较大的组件,等待时间可能会更久。根本原因还是文件体积太大,导致网络响应时间长。

 分析打包结果


遇到这种情况首先我们先找到文件体积大的原因,借助 webpack-bundle-analyzer插件,我们可以直观看到打包后每个文件的内容和大小。

  • 第一步:安装webpack-bundle-analyzer


技术13期:vue项目的webpack打包优化【前端篇】


  • 第二步:在vue.config.js文件中引入


技术13期:vue项目的webpack打包优化【前端篇】


  • 第三步:在webpack配置中使用该插件

 

技术13期:vue项目的webpack打包优化【前端篇】


  • 打包时间和结果如下:

 

技术13期:vue项目的webpack打包优化【前端篇】


技术13期:vue项目的webpack打包优化【前端篇】

 
可以看到最大的文件达到了1.9M,打包时间146秒,页面加载时间也达到30多秒,这简直是无法忍受的。
 

技术13期:vue项目的webpack打包优化【前端篇】


既然我们知道了原因,就可以着手解决问题。万能的互联网上可以找到很多解决方法。
例如: GzipcdnsplitChunk、图片压缩 等等,下面会挑几个 有意思 的方法聊聊。


Gzip


gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip


目前主流的浏览器,Chrome、firefox、IE等都支持该协议。常见的服务器如ApacheNginxIIS同样支持gzip要使用gzip功能:


  • 第一步:在服务器端开启,以nginx为例子,在配置文件中添加下面代码


技术13期:vue项目的webpack打包优化【前端篇】


  • 参数解释如下:


gzip: 决定是否开启gzip模块。
gzip_disable(IE5.5IE6 SP1使用msie6参数来禁止gzip压缩 )。指定哪些不需要gzip压缩的浏览器(将和User-Agents进行匹配)
gzip_vary:增加响应头”Vary: Accept-Encoding”
gzip_proxiedNginx做为反向代理的时候启用:
· 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_types:这个参数是指设置需要压缩的MIME类型,如果不在设置类型范围内的请求不进行压缩。
l gzip_comp_level:设置gzip压缩等级,等级越压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大。范围是1-9,根据需求设定。
gzip_buffers:设置用于处理请求压缩的缓冲区数量和大小。比如32 4K表示按照内存页(one memory page)大小以4K为单位(即一个系统中内存页为4K),申请32倍的内存空间。建议此项不设置,使用默认值。
gzip_http_version:用于识别http协议的版本,早期的浏览器不支持gzip压缩,用户会看到乱码,所以为了支持前期版本加了此选项。默认在http/1.0的协议下不开启gzip压缩。

  • 第二步:配置完成后,需要重启一下nginx


  • 第三步:在vue项目中进行相关配置


首先安装compression-webpack-plugin插件
 技术13期:vue项目的webpack打包优化【前端篇】

  • 第四步:在webpack配置中使用该插件

 

技术13期:vue项目的webpack打包优化【前端篇】


重新打包项目,再次访问页面我们可以看到在content-encoding一列出现了gzip说明配置成功了,1.9M的文件压缩之后只有599k,压缩比例达到70%左右,页面 加载速 度有了质的飞跃,页面出现只用了3.32s
 

技术13期:vue项目的webpack打包优化【前端篇】


当然,还有其他的压缩算法可以选择,例如Brotli,据说是比gzip压缩效果更好,感兴趣的读者可以试验一下。


外部引入模块(CDN)


我们可以将一些第三方组件通过cdn的方式引入,从而减小打包的文件数量,可以缩短打包时间和减小最后的文件体积。 下面我们将 vue vuex vue-router element-ui 使用 cdn 引入。

  • 第一步:在public/index.html文件中引入cdn链接

 

技术13期:vue项目的webpack打包优化【前端篇】


  • 第二步:在vue.config.js 配置文件中设置 externals 属性


技术13期:vue项目的webpack打包优化【前端篇】


其中属性名是引入的模块名,值是需要替换的变量,这个值必须和 cdn 中提供的一样,其作用是不打包使用外部引入的扩展,也就是 build 的时候不打包该模块。

  • 打包时间和结果如下:


技术13期:vue项目的webpack打包优化【前端篇】


技术13期:vue项目的webpack打包优化【前端篇】


可以看到打包出来的文件 明显小了 chunk-vendors1.9M减小到了1.14M
 

技术13期:vue项目的webpack打包优化【前端篇】


打包时间为107秒,配合使用gzip页面加载时间为2.65秒,不过如果cdn链接失效会导致资源缺失。


异步组件


在开发的时候,需要合理的划分各模块,做到首屏加载的时候只读取必要的模块,其他模块在需要的时候才从服务器加载。通过这种异步加载组件的方式,在打包的时候就不会把相关的组件打包到首屏相关的js中,可以减少首屏渲染相关文件的大小。

举个例子,一开始在代码中通过下面的方式引入“floatLabel”这个组件,这个组件引入了cytoscape.jsklay.js两个库,这意味着一开始它们都会被加载(可以参考CDN模块的打包结果)。
 

技术13期:vue项目的webpack打包优化【前端篇】


但是这个floatLabel组件在最开始是不会被使用到的,于是我们通过动态引入的方式引入它。

技术13期:vue项目的webpack打包优化【前端篇】


  • 打包时间和结果如下:

 

技术13期:vue项目的webpack打包优化【前端篇】


技术13期:vue项目的webpack打包优化【前端篇】


可以看到chunk-vendors已将减少到了178.64KB,打包时间也减少到了75秒,页面出现的时间变为了1.26s

技术13期:vue项目的webpack打包优化【前端篇】


这个时候最大的文件已经变成了klay.jscytoscape.jsjquery.js的这个chunk,如果看着不舒服想把他们拆开,可以用splitChunks将他们拆开,或者有cdn资源的话也可以通过cdn引入。


splitChunks


splitChunks字面意思就是 拆分chunks vue.config.js中添加下面的配置。
 

技术13期:vue项目的webpack打包优化【前端篇】


  • 打包的结果如下:


技术13期:vue项目的webpack打包优化【前端篇】


 
可以看到刚才993K的文件被拆成了几个稍微小一点的包。 但是这么做对首屏加载影响不大,因为一开始都没有加载到这几个包。而且几个几百K的包和一个1M左右的包哪种方式比较好就需要进一步评估了。


总 结

上面提到的都是vue项目里面会常用到的一些webpack相关的优化,并不是说都用上了就是好的。大家需要根据项目的实际情况进行选择,没有绝对正确的优化方法,只有尝试过后才能找到最合适的打包方式。
当然还有很多别的方案没有提及,比如DllPlugin、图片压缩、Happypack等,感兴趣的朋友们可以多尝试、多比对,合适的打包方案总是要经过大量的实验得出来的。最后再推荐TerserPlugin(可以屏蔽输出)和ProgressBarPlugin(记录打包时间)两个插件,个人感觉挺好用的,其实webpack还有很多好用的插件,大家可以多多挖掘。
注:上面的页面加载时间也会受到网速的影响,仅供参考。


作者:黄奕鑫
编辑:詹思璇
 


想学习更多技术内容

别忘了关注普适极客