vue项目首屏加载时间优化实战


Posted in Javascript onApril 23, 2019

问题

单页面应用的一个问题就是首页加载东西过多,加载时间过长。特别在移动端,单页面应用的首屏加载优化更是绕不开的话题。下面我会写出我在项目中做的一些优化,希望大家能够相互讨论,共同进步。

我的项目 vue-cli3构建的,vue+vue-router+vuex,UI框架选用 element-ui,ajax方案选用 axios,服务器使用Nginx 。用到的这些技术都是现在用的比较广泛的,看到这篇文章,我估计你和我用的技术应该差不多。

第一步:webpack-bundle-analyzer 分析

首页我们来看看没有经过任何优化的打包分析,vue-cli3的项目直接 vue-cli-service build --report 就会生成一个report.html,打开这个html就能看到,不是vue-cli3的项目需要自行安装这个插件,参考链接, 点击 。

vue项目首屏加载时间优化实战

如上图所示在vendor比较大的文件有element,moment,echart,还有jquery,然后还有一些没见过的vue-qriously这些组件,接下来我们来一步一步让vendor变小

第二步:初步优化

1. 仔细考虑组件是否需要全局引入

在我们的main.js,我发现有很多组件被全局引入,其中有些组件只有1,2个页面用到,这些组件不需要全部引入

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中删除,移到具体的页面中去。

2. 手动引入 ECharts 各模块

默认引入 ECharts 是引入全部的```import * as 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'

3.使用更轻量级的工具库

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

vue项目首屏加载时间优化实战

经过上面的三步初步优化,我们可以看到vendor.js变小了很多,去除了moment,我们项目之前echart就是按需加载的。

第三步:CDN优化

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

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,请 参考地址

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: '$'
  }
 },
}

3. 去除vue.use相关代码

需要注意的是,通过 CDN 引入,在使用 VueRouter Vuex ElementUI 的时候要改下写法。CDN会把它们挂载到window上,因此不再使用Vue.use(xxx)

也不在需import Vue from 'vue', import VueRouter from 'vue-router' 等。

vue项目首屏加载时间优化实战

剔除全家桶和Element-ui等只有,剩下的需要首次加载 vendors 就很小了。

使用 CDN 的好处有以下几个方面

(1)加快打包速度。分离公共库以后,每次重新打包就不会再把这些打包进 vendors 文件中。

(2)CDN减轻自己服务器的访问压力,并且能实现资源的并行下载。浏览器对 src 资源的加载是并行的(执行是按照顺序的)。

第四步:检查Nginx 是否开启 gzip

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

vue项目首屏加载时间优化实战 

vue项目首屏加载时间优化实战

第五步:检查路由懒加载

路由组件如果不按需加载的话,就会把所有的组件一次性打包到app.js中,导致首次加载内容过多,vue官方文档中也有提到, 地址 。

{
 name: 'vipBoxActivity',
 path:'vipBoxActivity',
 component(resolve) {
  require(['COMPONENTS/vipBox/vipBoxActivity/main.vue'], resolve)
 }
},
{
 path: 'buyerSummary',
 name: 'buyerSummary',
 component: () => import('VIEWS/buyer/buyerSummary/index'),
},

上面的两种引入组件的方法都是正确的,都能实现路由的懒加载。

最后

最后我们可以发现vendor.js的大小减少了很多。其中第一步到第三步我们项目中都没做,第四步和第五步我们做了。如果读者你没做,一定要注意了。最后希望这篇文字能够对大家有一点点帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
解决css和js的{}与smarty定界符冲突问题的两种方法
Sep 10 Javascript
JavaScript实现计算字符串中出现次数最多的字符和出现的次数
Mar 12 Javascript
jQuery实现的支持IE的html滑动条
Mar 16 Javascript
基于Javascript实现返回顶部按钮
Feb 29 Javascript
javascript 数组的正态分布排序的问题
Jul 31 Javascript
vue.js的提示组件
Mar 02 Javascript
webpack开发跨域问题解决办法
Aug 03 Javascript
Vue导出json数据到Excel电子表格的示例
Dec 04 Javascript
Bootstrap-table自定义可编辑每页显示记录数
Sep 07 Javascript
ES6知识点整理之模块化的应用详解
Apr 15 Javascript
在vue中使用echarts(折线图的demo,markline用法)
Jul 20 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
Jul 21 Javascript
灵活使用console让js调试更简单的方法步骤
Apr 23 #Javascript
详解实现一个通用的“划词高亮”在线笔记功能
Apr 23 #Javascript
Vue源码学习之关于对Array的数据侦听实现
Apr 23 #Javascript
vue的keep-alive中使用EventBus的方法
Apr 23 #Javascript
js继承的这6种方式!(上)
Apr 23 #Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
Apr 23 #jQuery
node.js基于socket.io快速实现一个实时通讯应用
Apr 23 #Javascript
You might like
超外差式晶体管收音机的组装与统调
2021/03/01 无线电
Gregarius中文日期格式问题解决办法
2008/04/22 PHP
php 字符过滤类,用于过滤各类用户输入的数据
2009/05/27 PHP
PHP用mysql_insert_id()函数获得刚插入数据或当前发布文章的ID
2016/11/25 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
ASP.NET中基于JQUERY的高性能的TreeView补充
2011/02/23 Javascript
javascript数组去重3种方法的性能测试与比较
2013/03/26 Javascript
自动刷新网页,自动刷新当前页面,JS调用
2013/06/24 Javascript
浅析Js(Jquery)中,字符串与JSON格式互相转换的示例(直接运行实例)
2013/07/09 Javascript
jquery阻止后续事件只执行第一个事件
2014/07/24 Javascript
js实时获取并显示当前时间的方法
2015/07/31 Javascript
浅析js中substring和substr的方法
2015/11/09 Javascript
jQuery控制div实现随滚动条滚动效果
2016/06/07 Javascript
AngularJS 路由和模板实例及路由地址简化方法(必看)
2016/06/24 Javascript
AngularJS 单元测试(二)详解
2016/09/21 Javascript
DropDownList控件绑定数据源的三种方法
2016/12/24 Javascript
基于jQuery封装的分页组件
2017/06/26 jQuery
JS脚本实现网页自动秒杀点击
2018/01/11 Javascript
JS实现的文字间歇循环滚动效果完整示例
2018/02/13 Javascript
vue和react等项目中更简单的实现展开收起更多等效果示例
2018/02/22 Javascript
JavaScript调用模式与this关键字绑定的关系
2018/04/21 Javascript
vue实现的微信机器人聊天功能案例【附源码下载】
2019/02/18 Javascript
jQuery中实现text()的方法
2019/04/04 jQuery
深入解析Vue源码实例挂载与编译流程实现思路详解
2019/05/05 Javascript
原生js实现简单轮播图
2020/10/26 Javascript
python 采用paramiko 远程执行命令及报错解决
2019/10/21 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
加拿大购物频道:The Shopping Channel
2016/07/21 全球购物
迪卡侬波兰体育用品商店:Decathlon波兰
2020/03/31 全球购物
Oasis服装官网:时尚女装在线
2020/07/09 全球购物
大四毕业生学习总结的自我评价
2013/10/31 职场文书
毕业生的求职信范文分享
2013/12/04 职场文书
2015教师个人年度工作总结
2015/10/23 职场文书
图文详解nginx日志切割的实现
2022/01/18 Servers
《异世界四重奏》剧场版6月10日上映 PV视觉图原创角色发表
2022/03/20 日漫
NASA 机智号火星直升机拍到了毅力号设备碎片
2022/04/29 数码科技