webpack异步加载的原理

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的第一个参数[]
也是请求下载的模块,如果想加载A require.ensure(['A.js'],function) 即可

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

 

entry.js 依赖三个 js。

  • Abtn-work.js 是封装了 abtn按钮点击后,才执行的业务逻辑
  • Bbtn-work.js 是封装了 bbtn按钮点击后,才执行的业务逻辑
  • 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打包后,形成

 
image.png

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

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

 
image.png

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

点击 abtn,

 
image.png

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

点击 bbtn

 
image.png

 

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

ok 全部完成

转自:https://www.jianshu.com/p/9fa38e536033

require.ensure的用法;异步加载-代码分割;的更多相关文章

  1. jsTree 的简单用法--异步加载和刷新数据

    首先这两个文件是必须要引用的,还有就是引用 jQuery 文件就不说了: <link href="/css/plugins/jsTree/style.min.css" rel ...

  2. webpack中利用require.ensure()实现按需加载

    webpack中的require.ensure()可以实现按需加载资源包括js,css等,它会给里面require的文件单独打包,不和主文件打包在一起,webpack会自动配置名字,如0.js,1.j ...

  3. webpack异步加载业务模块

    虽然把我们用到的JS文件全部打包一个可以节省请求数,但如果打包后的JS文件过大,那么也容易出现白屏现象,许多操作失灵.而且一些区域是点到才出现,那么相关的JS其实可以剥离出这个大JS文件外.这就涉及到 ...

  4. Javascript 异步加载详解(转)

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...

  5. Javascript 异步加载详解

    Javascript 异步加载详解 本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy ...

  6. javascript异步加载详解(转)

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...

  7. 转:web前端面试题合集 (Javascript相关)(js异步加载详解)

    1. HTTP协议的状态消息都有哪些? 1**:请求收到,继续处理2**:操作成功收到,分析.接受3**:完成此请求必须进一步处理4**:请求包含一个错误语法或不能完成5**:服务器执行一个完全有效请 ...

  8. [转载]Javascript 同步异步加载详解

    http://handyxuefeng.blog.163.com/blog/static/4545217220131125022640/ 本文总结一下浏览器在 javascript 的加载方式. 关键 ...

  9. QFramework 使用指南 2020(九):Res Kit(3)异步加载 与 异步队列加载

    在上一篇我们了解了 Res Kit 的一些背后设计原理,讲解了一些概念,比如:开发阶段.真机阶段等. 在这一篇,我们回到 Res Kit 使用细节上. 在 Res Kit 的第一篇,我们介绍了 Res ...

随机推荐

  1. ORA-12538;ORA-12154;使用PL/SQL dve无法连接远程服务器上的oracle数据库,同时本机上也安装了一个oracle数据库

    问题描述:本人使用PL/SQL dve连接远程服务器上的oracle数据库,一直是没有问题的.我想提高下自己在数据库方面的能力就在自己的笔记本上安装了一个oracle数据库实例,安装并配置好之后,使用 ...

  2. zabbix监控磁盘IO

    我这里有两种方法,感觉都不错.我这里主要是写一下监控的脚本. 1.使用iostat命令监控 1)首先打开配置文件的自定义脚本功能,然后编写脚本. #!/bin/bash ];then echo &qu ...

  3. SQL取最大值编码(自动编码)

    SQL取最大值编码(自动编码) 用途 : 使用SQL语法做出自动编码效果,例如将单号自动+1后,产生该笔单号 Table说明 SQL语法 SELECT 'A'+REPLICATE('0',7-len( ...

  4. C#中类为什么要实例化

    在使用C#语言时,发现一下有关类实例化的问题,在此之前先复习一下类和对象的概念,类是一个抽象体,是对一类事物的抽象体:而对象就是一个具体的事物,对象的抽象就是类.车就是一个类,而车包括面包车,小汽车, ...

  5. ccf-20161203--权限查询

    这题我的思路是将用户直接与他的权限联系起来.比如: 用户 角色 权限 Alice hr crm:2直接转变为:Alice: crm:2 题目与代码如下: 问题描述 试题编号: 201612-3 试题名 ...

  6. iOS-单选cell的实现

    一.思路 先设置一个chooseCelltag标记(类型为NSIndexPath),然后在点击cell触发的时候,如果tag设置有值,就设置 UITableViewCell *selectedCell ...

  7. B - Modular Inverse

    The modular modular multiplicative inverse of an integer a modulo m is an integer x such that a-1≡x ...

  8. Mac OS 安装Fiddler

    Mono安装 首先,Mac下需要使用.Net编译后的程序,需要用到跨平台的方案Mono(现阶段微软已推出跨平台的方案.Net Core,不过暂时只支持控制台程序).安装程序可以从http://www. ...

  9. Python字符串操作之字符串分割与组合

    12.字符串的分割和组合 12.1 str.split():字符串分割函数 通过指定分隔符对字符串进行切片,并返回分割后的字符串列表. 语法: str.split(s, num)[n] 参数说明: s ...

  10. 23个Python爬虫开源项目代码

    今天为大家整理了23个Python爬虫项目.整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快 1.WechatSogou [1]– 微信公众号 ...