vue项目首屏加载优化

在我们使用vue全家桶搭载项目时,vue-cli搭建脚手架,配合vue-router控制路由,vuex控制状态及复杂组件通讯,实现顺畅的spa应用,但是往往在项目应用插件框架时后首屏加载时间非常长。故此可做一些优化。

1. 安装webpack-bundle-analyzer插件,用以检测哪个包占的空间多。

$ npm install --save-dev webpack-bundle-analyzer

配置相关参数

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [
	new BundleAnalyzerPlugin(
     	{
          analyzerMode: 'server',
          //  可以是`server`,`static`或`disabled`。
		 //  在`server`模式下,分析器将启动HTTP服务器来显示软件包报告。
		 //  在`static`模式下,会生成带有报告的单个HTML文件。
		 //  在`disabled`模式下,你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats 			JSON文件。
          analyzerHost: '127.0.0.1', // server模式下启动的http服务器
          analyzerPort: 8888, // 运行后的端口号
          reportFilename: 'report.html', //用于 disabled模式
          defaultSizes: 'parsed', // 应该是`stat`,`parsed`或者`gzip`中的一个。
          openAnalyzer: true, //自动打开报告
          generateStatsFile: false, //用于disabled模式
          statsFilename: 'stats.json', // static模式
          statsOptions: null,
          logLevel: 'info'  // 日志级别。可以是'信息','警告','错误'或'沉默'。
        }
    ),
]

这样就安装好了,之后运行npm run build打包,就会打开一个打包生成文件的模块组成图在这里插入图片描述

1. 初步优化,减少全局组件引入(是否放在main.js),按需引入需要的模块(echarts按需引入等),使用轻量级数据库(moment.js 切换 data-fns等)。
考虑是否组件需要全局引入
在main.js,发现有很多组件被全局引入,其中有些组件只有个别页面用到,这些组件并不需要全局引入。因此可以放到特定组件中。

import ImageComponent from 'COMMON/imageComponent'
import InfiniteLoading from 'COMMON/infiniteLoading'
import SearchDialog from 'COMMON/SearchDialog'
import BasicTable from 'COMMON/BasicTable'
import VueQriously from 'vue-qriously'

Vue.use(ImageComponent)
Vue.use(InfiniteLoading) // 可以去除
Vue.use(SearchDialog) // 可以去除
Vue.use(BasicTable)  // 可以去除
Vue.use(VueQriously)  // 可以去除

上面一段代码是main.js中的代码,其中ImageComponent是用来处理图片的,用到的页面很多,其他的组件都只要较少的页面用到,我们在main.js中删除,移到具体的页面中去。

手动引入Echarts等模块
默认引入 ECharts 是引入全部的import ECharts from 'echarts'我们只需要部分组件,只需引入自己需要的部分。参考地址,点击

import VueECharts from 'vue-echarts/components/ECharts.vue'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/pie'
import 'echarts/lib/component/title'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/markPoint'

使用更加轻量级的工具库
moment是处理时间的标杆,但是它过于庞大且默认不支持tree-shaking,而且我们的项目中只用到了moment(), format(), add(), subtract()等几个非常简单的方法,有点大材小用,所以我们用 date-fns 来替换它,需要什么方法直接引入就行。

优化前
在这里插入图片描述
优化后
在这里插入图片描述
经过上面的三步初步优化,减少组件全局引入,手动按需引入echarts,使用轻量级的工具库。我们可以看到vendor.js变小了很多,注意这个vendor.js文件,它是项目所有依赖的集成(包括vue vue-router axios echarts ele等)vendor.js一般是将所有引用的库打包在了一起

2. CDN优化。
进过上面的优化,发现 Vue 全家桶以及 ElementUI 仍然占了很大一部分 vendors 体积,这部分代码是不变的,但会随着每次 vendors 打包改变 hash 重新加载。我们可以使用 CDN 剔除这部分不经常变化的公共库。我们将vue,vue-router,vuex,axios,jquery,underscore,使用CDN资源引入。国内的CDN服务推荐使用 BootCDN

CDN的全称是Content Delivery Network,内容分发网络

CDN加速简单的来说,就是把原服务器上数据复制到其他服务器上,用户访问时,哪台服务器近访问到的就是哪台服务器上的数据。

1.首先我们在index.html中,添加CDN代码

<link href="https://cdn.bootcss.com/element-ui/2.7.2/theme-chalk/index.css" rel="stylesheet">
  </head>
  <body>
    <div id="app"></div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
    <script src="https://cdn.bootcss.com/vue-router/3.0.4/vue-router.min.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
    <script src="https://cdn.bootcss.com/element-ui/2.7.2/index.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/underscore.js/1.9.1/underscore-min.js"></script>
  </body>
</html>

2.在vue.config.js中加入webpack配置代码,关于webpack配置中的externals,请参考地址
externals(翻译:外部环境)的作用是从打包的bundle文件中排除依赖。

换句话说就是让在项目中通过import引入的依赖在打包的时候不会打包到bundle包中去,而是通过script(CDN)的方式去访问这些依赖
// 忽略打包的第三方库

  • externals 对象属性解析:
  • ‘包名’ : ‘在项目中引入的名字’
  • 以element-ui举例 我再main.js里是以
  • import ELEMENT from ‘element-ui’
  • Vue.use(ELEMENT, { size: ‘small’ })
  • 这样引入的,所以我的externals的属性值应该是ELEMENT
	
configureWebpack: {
  externals: {
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex': 'Vuex',
    'element-ui': 'ELEMENT',
    'axios': 'axios',
    'underscore' : {
      commonjs: 'underscore',
      amd: 'underscore',
      root: '_'
    },
    'jquery': {
      commonjs: 'jQuery',
      amd: 'jQuery',
      root: '$'
    }
  },
}
  1. 去除vue.use相关代码

需要注意的是,通过 CDN 引入,在使用 VueRouter Vuex ElementUI 的时候要改下写法。CDN会把它们挂载到window上,因此不再使用Vue.use(xxx)
也不需要再import Vue from ‘vue’, import VueRouter from ‘vue-router’ 等。
在这里插入图片描述
剔除全家桶和Element-ui等只有,剩下的需要首次加载 vendors 就很小了。
使用 CDN 的好处有以下几个方面

(1)加快打包速度。分离公共库以后,每次重新打包就不会再把这些打包进 vendors 文件中。
(2)CDN减轻自己服务器的访问压力,并且能实现资源的并行下载。浏览器对 src 资源的加载是并行的(执行是按照顺序的)。

3. 检查Nginx 是否开启 gzip。

如下图所示,开启了gzip后js的大小比未开启gzip的js小2/3左右,所以如果没开启gzip,感觉我们做的再多意义也不大,如何看自己的项目有没有开启gzip,如下图所示,开启了gzip,在浏览器的控制台Content-Encoding一栏会显示gzip,否则没有。Nginx如果开启gzip,请自行搜索,或者叫服务端来开启。
在这里插入图片描述
在这里插入图片描述

4. 检查路由懒加载。
路由组件如果不按需加载的话,就会把所有的组件一次性打包到app.js中,导致首次加载内容过多,vue官方文档中也有提到,这种优化,就是将每个组件的js代码独立出来,在使用到这个组件时,才向服务器请求文件,并且请求过一次后就会缓存下来,再次使用到这个组件时,就会使用缓存,不再发送请求。
配置很简单,只需要在vue-router中添加一些简单的配置即可地址

{
  name: 'vipBoxActivity',
  path:'vipBoxActivity',
  component(resolve) {
    require(['COMPONENTS/vipBox/vipBoxActivity/main.vue'], resolve)
  }
},

{
  path: 'buyerSummary',
  name: 'buyerSummary',
  component: () => import('VIEWS/buyer/buyerSummary/index'),
},

5. 去掉打包的map文件。
打开js,可以看到,里面有许多.map文件,而且很多都很大,如图最后一个3M多,map文件是什么鬼?这些文件主要是帮助我们线上调试代码,查看样式。所以为了避免部署包过大,通常都不生成这些文件。
在这里插入图片描述

在 config/index.js 文件中将productionSourceMap 的值设置为false. 再次打包就可以看到项目文件中已经没有map文件

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值