vue项目性能优化

一、 使用webpack-bundle-analyzer 分析打包后的生成的文件结构进行优化;

在package.json配置 "analyz": "NODE_ENV=production npm_config_report=true npm run build" ,然后运行 npm run analyz 即可;

image.png
image.png

通过分析图,可以查看哪些有重复的文件或者哪个文件较大从而相应的进行优化;

这里提一下,左上角的stat、parsed及gzip表示什么意思:
stat表示文件的输入大小,parsed表示文件的输出大小,gzip表示通过gzip压缩运行解析的包/模块的大小;https://github.com/webpack-contrib/webpack-bundle-analyzer#size-definitions
这三个状态文件体积相差很大,可见使用gzip的重要性。

二、启用 gzip压缩;

1、安装 compression-webpack-plugin

npm install compression-webpack-plugin --save-dev
这里有个坑,就是如果你的vue版本为2.5.2 及以下 webpack版本为3.6.0及以下时,建议安装compression-webpack-plugin的版本为1.0.0-beta.1 而不是2.0.0,否则可能打包时会报

ValidationError: Compression Plugin Invalid Options

options should NOT have additional properties
2、将vue项目中的 config/index.js中productionGzip: false改为 productionGzip: true;

打包后,可以看到.gz后缀文件了:


image.png
3、然后后台开启gzip模式:

开启 nginx gzip ,在 nginx.conf 配置文件中 配置

http {  //在 http中配置如下代码,
  
   gzip on;
   gzip_disable "msie6"; 
   gzip_vary on; 
   gzip_proxied any;
   gzip_comp_level 8; #压缩级别
   gzip_buffers 16 8k;
   #gzip_http_version 1.1;
   gzip_min_length 100; #不压缩临界值
   gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
 }

保存退出 ,并 重启 nginx

 systemctl reload nginx.service  
 systemctl restart nginx.service
4、测试访问

a、未开启gzip的情况


未开启gzip的情况
未开启gzip的体积

b、开启gzip的情况


开启了gzip的情况

开启了gzip的体积

可以看到 开启后响应头里有 content-encoding: gzip,且体积减少了一半还多。

三、解决vendor.js体积过大的问题

上面我们可以看到未经过gzip压缩,vendor.js体积有730kb,体积挺大的,vendor.js是第三方库经webpack打包而生成的集合;如下面的main.js 引用的第三方库ElementUI 、axios会被打包在vendor.js中


image.png

其实 我们可以使用cdn来引入第三方库:

1、选用cdn服务商

如 选用unpkg来作为第三方提供 https://unpkg.com 或者 https://www.bootcdn.cn/ 如我想要axios包则输入网址为 https://unpkg.com/axios/ (末尾加斜杠代表你要查询该库的所有版本列表)

2、在index.html中将你所需的第三方库的链接加入即可:

我以axios为例:


image.png

注:应该加入到<div id="app"></div>前面

3、启用DNS预解析

在index.html的header中加入

  <meta http-equiv="x-dns-prefetch-control" content="on">
  <link rel="dns-prefetch" href="cdn域名">
  <meta http-equiv="x-dns-prefetch-control" content="on">
  <link rel="dns-prefetch" href="https://cdn.bootcss.com">
4、webpack.base.conf 中添加 externals 来告诉webpack我们这些第三方库不需要打包
image.png
  externals:{
    "axios":"axios"  // key--axios 为你在项目中使用的名字,value--axios 为axios库的模块名为axios
  },

库的模块名可以在源码中看,如element-ui 则为ELEMENT


image.png
5、去除原有的引用

包括 import axios from 'axios';Vue.use(axios )
,当然如果为了避免去除import axios from 'axios';后导致很多eslint 警告,你可以保留import axios from 'axios';; 参考依据: 外部扩展(externals)

https://webpack.js.org/configuration/externals/

完成后打包一下观察vendor.js的体积变化:

未使用cdn的情况
使用cdn以后

可以看到vendor.js减少了12kb;也就是axios.min.js的大小。这里其实还可以将vue、element ui 都拎出来,可以减少很多体积;

题外话:

a、app.js
app.js 入口文件打包的结果,里面将项目中的api接口名及请求和响应等拦截器、路由组件关系等文件全部压缩打包了,大部分为我们自己编写的代码

b、manifest.js
manifest.js 模块化的应用程序的所有代码,里面是 建立hash映射关系的文件


image.png

c、vendor.js 第三方库,一般是node_modules里面的依赖进行打包

d、vendor-async.js
vue中mixin里的所有代码都会打包至vendor-async.js中

四、采用webpack.DllReferencePlugin将不常变更的库免二次打包编译;

这个可大大减少编译时间,同时可使用未变更的文件的缓存;
具体可参考
1、 Webpack的dll功能
2、webpack进阶——DllPlugin优化打包性能(基于vue-cli)

其实采用webpack.DllReferencePlugin跟上面介绍的--解决vendor体积过大的问题中的 externals方法存在异曲同工之处,貌似它们间有差别,但这个差别有待考证:


image.png

经过查看的回答发现webpack.DllReferencePlugin可以由autodll-webpack-plugin完美替代,这点待后面有时间再研究;

五、路由懒加载

使用

// 官方写法
const CardActConsume = () => import('@/components/club/CardActConsume')
// 自己的写法
const CardBuyConsume = (resolve) => {
  import('@/components/club/CardBuyConsume').then((module) => {
    resolve(module)
   });
 }
...
    {
          path: '/club/:id/cardactconsume',
          name: 'clubcardactconsume',
          component: CardActConsume,
   }
...


替代原有的

import CardActConsume from '@/components/club/CardBuyConsume'

这个就不多说了 ,可见官方文档: https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E6%8A%8A%E7%BB%84%E4%BB%B6%E6%8C%89%E7%BB%84%E5%88%86%E5%9D%97;另外可以把组件按组分块打包成一个js:

image.png

六、webpack 配置文件记得区分开发环境和生产环境

生产环境不要包含HotModuleReplacementPlugin 等没有必要的插件;

七、待续

待续

推荐资料:
1、https://webpack.docschina.org/guides/lazy-loading/
2、 vue-cli中的webpack配置

参考资料:
1、完美解决 vue webpack 单页面 加载慢 gzip 访问 vendor.js 打包文件过大问题
2、 使用vue-cli生成的vendor.js文件太大,有办法减少体积吗?
3、[https://juejin.im/post/5a291092518825293b50366d#heading-2](VueSPA 首屏加载优化实践)

推荐阅读更多精彩内容