浅谈vue项目优化之页面的按需加载(vue+webpack)


Posted in Javascript onDecember 11, 2017

通过vue写的单页应用时,可能会有很多的路由引入。当打包构建的时候,javascript包会变得非常大,影响加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件,这样就更加高效了。这样会大大提高首屏显示的速度,但是可能其他的页面的速度就会降下来。结合Vue的异步组件和webpackde code splitting feature,轻松实现路由组件的懒加载。

就像图片的懒加载一样,如果客户根本就没有看到那些图片,而我们却在打开页面的时候全部给加载完了,这样会大大的增加请求的时间,降低用户的体验程度。懒加载在很多的网站都有用到,比如淘宝、京东等等这样的购物网站,上面的图片链接等等都很多,如果你把滚轴迅速的往下拉的时候,你可能会看到图片加载的情况。

单页应用也是一样,用户可能没有通过点击跳转到其他的的页面,而是只在主页面进行了停留,那么我们就没有必要把其他页面的资源全部加载过来。如果用户点进去再加载。这样就可以大大提高请求时间,提高用户的体验程度。

webpack中提供了require.ensure()来实现按需加载。以前引入路由是通过import 这样的方式引入,改为const定义的方式进行引入。

不进行页面按需加载引入方式:import  home   from '../../common/home.vue'

进行页面按需加载的引入方式:const  home = r => require.ensure( [], () => r (require('../../common/home.vue')))

下面的内容讲解的更为详细

webpack ensure相信大家都听过。有人称它为异步加载,也有人说做代码切割,那这个家伙到底是用来干嘛的?其实说白了,它就是把js模块给独立导出一个.js文件的,然后使用这个模块的时候,webpack会构造script dom元素,由浏览器发起异步请求这个js文件。

场景分析:

比如应用的首页里面有个按钮,点击后可以打开某个地图。打开地图的话就要利用百度地图的js,于是我们不得不在首页中把百度地图的js一起打包进去首页,一个百度地图的js文件是非常大的,假设为1m,于是就造成了我们首页打包的js非常大,用户打开首页的时间就比较长了。

有没有什么好的解决方法呢?

解决1

既然打包成同一个js非常大的话,那么我们完全可以把百度地图js分类出去,利用浏览器的并发请求js文件处理,这样的话,会比加载一个js文件时间小得多。嗯,这也是个不错的方案。为baidumap.js配置一个新的入口就行了,这样就能打包成两个js文件,都插入html即可(如果baidumap.js被多个入口文件引用的话,也可以不用将其设置为入口文件,而且直接利用CommonsChunkPlugin,导出到一个公共模块即可)可以参考我之前文章webpack模块打包

那还有没有更好的解决方案呢?

解决2

当然还是有的!我们细想,百度地图是用户点击了才弹出来的,也就是说,这个功能是可选的。那么解决方案就来了,能不能在用户点击的时候,我在去下载百度地图的js.当然可以。那如何实现用户点击的时候再去下载百度地图的js呢?于是,我们可以写一个按钮的监听器

mapBtn.click(function() {
 //获取 文档head对象
 var head = document.getElementsByTagName('head')[0];
 //构建 <script>
 var script = document.createElement('script');
 //设置src属性
 script.async = true;
 script.src = "http://map.baidu.com/.js"
 //加入到head对象中
 head.appendChild(script);
})

上面的几行代码对大家来说都不难。可以在点击的时候,才加载百度地图,等百度地图加载完成后,在利用百度地图的对象去执行我们的操作。ok,讲到这里webpack.ensure的原理也就讲了一大半了。它就是
把一些js模块给独立出一个个js文件,然后需要用到的时候,在创建一个script对象,加入到document.head对象中即可,浏览器会自动帮我们发起请求,去请求这个js文件,在写个回调,去定义得到这个js文件后,需要做什么业务逻辑操作。

ok,那么我们就利用webpack的api去帮我们完成这样一件事情。点击后才进行异步加载百度地图js,上面的click加载js时我们自己写的,webpack可以轻松帮我们搞定这样的事情,而不用我们手写

mapBtn.click(function() {
 require.ensure([], function() {
  var baidumap = require('./baidumap.js') //baidumap.js放在我们当前目录下
 })
})

搞定!当然还是分析一下。require.ensure这个函数是一个代码分离的分割线,表示 回调里面的require是我们想要进行分割出去的,即require('./baidumap.js'),把baidumap.js分割出去,形成一个webpack打包的单独js文件。当然ensure里面也是可以写一些同步的require的,比如

var sync = require('syncdemo.js')  //下面ensure里面也用到
mapBtn.click(function() {
 require.ensure([], function() {
  var baidumap = require('./baidumap.js') //baidumap.js放在我们当前目录下
  var sync = require('syncdemo.js') //这个不会独立出去,因为它已经加载到模块缓存中了
 })
})

也就是说,ensure会把没有使用过的require资源进行独立分成成一个js文件. require.ensure的第一个参数是什么意思呢?[], 其实就是 当前这个 require.ensure所依赖的其他 异步加载的模块。你想啊?如果A 和 B都是异步加载的,B中需要A,那么B下载之前,是不是先要下载A啊?,所以ensure的第一个参数[]是它依赖的异步模块,但是这里需要注意的是,webpack会把参数里面的依赖异步模块和当前的需要分离出去的异步模块给一起打包成同一个js文件,这里可能会出现一个重复打包的问题,假设A 和 B都是异步的, ensure A 中依赖B,ensure B中 依赖A,那么会生成两个文件,都包含A和B模块。 如果想加载A require.ensure([‘A.js'],function) 即可

说完了上面的原理。下面就实践一下

浅谈vue项目优化之页面的按需加载(vue+webpack)

entry.js 依赖三个 js。

  1. Abtn-work.js 是封装了 abtn按钮点击后,才执行的业务逻辑
  2. Bbtn-work.js 是封装了 bbtn按钮点击后,才执行的业务逻辑
  3. util.js 是封装了 entry.js需要利用的工具箱

针对上面的需求,优化方案

假设 Abtn-work.js Bbtn-work.js util.js都是非常大的文件因为 Abtn-work.js Bbtn-work.js 都不是entry.js必须有的,即可能发生的操作,那么我们把他们利用异步加载,当发生的时候再去加载就行了

util.js是entry.js立即马上依赖的工具箱。但是它又非常的大,所以将其配置打包成一个公共模块,利用浏览器的并发加载,加快下载速度。ok,构思完成,开始实现

index.html

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>index</title>
 </head>
 <body>
  <div id="aBtn">Abtn</div>
  <div id="bBtn">Bbtn</div>
 </body>
</html>

定义了两个buttom

然后看看 entry.js

var util_sync = require('./util-sync.js')
alert(util_sync.data)
document.getElementById("aBtn").onclick = function() {
 require.ensure([], function() {
  var awork = require('./workA-async.js')
  alert(awork.data)
  //异步里面再导入同步模块--实际是使用同步中的模块
  var util1 = require('./util-sync.js')
 })
}
document.getElementById("bBtn").onclick = function() {
 require.ensure([], function() {
  var bwork = require('./workB-async.js')
  alert(bwork.data)
 })
}

可以看到,workA-async.js, workB-async.js 都是点击后才ensure进来的。什么时候加载完成呢?就是 require.ensure() 第二个函数参数,即回调函数,它表示当下载js完成后,发生的因为逻辑

webpack打包后,形成

浅谈vue项目优化之页面的按需加载(vue+webpack)

其实, 1.1… 2.2…就是我们ensure导出来的js文件

我们看看代码是如何加载的执行的,点击打包插入js后的html

浅谈vue项目优化之页面的按需加载(vue+webpack)

可以看到,并没有加载 ensure导出来的 1.1…js 2.2…js

点击 abtn,

浅谈vue项目优化之页面的按需加载(vue+webpack)

发现浏览器下载并加载了 1.1…js

点击 bbtn

浅谈vue项目优化之页面的按需加载(vue+webpack)

发现浏览器下载并加载了 2.2…js

vue项目优化,还有通过减少向服务器请求的次数来减少等待的时间。比如,一个页面的数据包括图片、文字等用户都已经加载完了,然后用户通过点击跳转到了另外一个界面。然后从另外一个界面通过返回又回到了原先的界面。如果没有设置的话,那么原先界面的信息就要重新向服务器请求得到。而通过vue提供的keep-alive可以是页面的已经请求的数据得以保存,减少请求的次数,提高用户的体验程度。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 面向对象继承
Nov 26 Javascript
jQuery中after()方法用法实例
Dec 25 Javascript
easyui validatebox验证
Apr 29 Javascript
基于jquery实现三级下拉菜单
May 10 Javascript
AngularJS获取json数据的方法详解
May 27 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
Jul 18 Javascript
JS抛物线动画实例制作
Feb 24 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
Feb 26 Javascript
JS双向链表实现与使用方法示例(增加一个previous属性实现)
Jan 31 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
Mar 05 Javascript
javascript实现留言板功能
Feb 08 Javascript
解决vue init webpack 下载依赖卡住不动的问题
Nov 09 Javascript
微信小程序使用radio显示单选项功能【附源码下载】
Dec 11 #Javascript
详解webpack编译多页面vue项目的配置问题
Dec 11 #Javascript
微信小程序使用checkbox显示多项选择框功能【附源码下载】
Dec 11 #Javascript
浅谈webpack编译vue项目生成的代码探索
Dec 11 #Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
Dec 11 #Javascript
Mac中安装nvm的教程分享
Dec 11 #Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
Dec 11 #jQuery
You might like
php下批量挂马和批量清马代码
2011/02/27 PHP
codeigniter自带数据库类使用方法说明
2014/03/25 PHP
php编写批量生成不重复的卡号密码代码
2015/05/14 PHP
Yii2创建控制器(createController)方法详解
2016/07/23 PHP
tp5 sum某个字段相加得到总数的例子
2019/10/18 PHP
js 页面执行时间计算代码
2009/03/04 Javascript
Extjs学习笔记之一 初识Extjs之MessageBox
2010/01/07 Javascript
jWiard 基于JQuery的强大的向导控件介绍
2011/10/28 Javascript
杨氏矩阵查找的JS代码
2013/03/21 Javascript
让新消息在网页标题闪烁提示的jQuery代码
2013/11/04 Javascript
Jquery中&quot;$(document).ready(function(){ })&quot;函数的使用详解
2013/12/30 Javascript
完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
2014/12/17 Javascript
js实现仿Windows风格选项卡和按钮效果实例
2015/05/13 Javascript
jQuery如何使用自动触发事件trigger
2015/11/29 Javascript
浅析BootStrap栅格系统
2016/06/07 Javascript
12306 刷票脚本及稳固刷票脚本(防挂)
2017/01/04 Javascript
js canvas实现写字动画效果
2018/11/30 Javascript
微信小程序 JS动态修改样式的实现方法
2018/12/16 Javascript
jQuery中each和js中forEach的区别分析
2019/02/27 jQuery
Python实现竖排打印传单手机号码易撕条
2015/03/16 Python
python使用pygame框架实现推箱子游戏
2018/11/20 Python
关于不懂Chromedriver如何配置环境变量问题解决方法
2019/06/12 Python
详解Python可视化神器Yellowbrick使用
2019/11/11 Python
Python使用qrcode二维码库生成二维码方法详解
2020/02/17 Python
Python进程Multiprocessing模块原理解析
2020/02/28 Python
pycharm 2018 激活码及破解补丁激活方式
2020/09/21 Python
详解Tensorflow不同版本要求与CUDA及CUDNN版本对应关系
2020/08/04 Python
Python 获取异常(Exception)信息的几种方法
2020/12/29 Python
CSS3中的display:grid,网格布局介绍
2019/10/30 HTML / CSS
哥伦比亚最大的网上商店:Linio哥伦比亚
2016/09/25 全球购物
优秀交警事迹材料
2014/01/26 职场文书
音乐节策划方案
2014/06/09 职场文书
2014年结对帮扶工作总结
2014/12/17 职场文书
公司员工管理制度
2015/08/04 职场文书
《蚂蚁和蝈蝈》教学反思
2016/02/22 职场文书
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python