JS异步加载库LABjs简易说明
为什么80%的码农都做不了架构师?>>>
一、关于LABjs的简单介绍
作者:Kyle Simpson
作用:动态并行加载脚本文件 以及 管理加载脚本文件的执行顺序
官网:http://www.labjs.com/
二、关于LABjs的使用
以下实例原文链接:http://www.au92.com/archives/labjs.html
更全更详细说明:http://labjs.com/documentation.php
实例1:
$LAB.script("script1.js").script("script2.js").script("script3.js").wait(function(){// 等待所有script加载完再执行这个代码块 script1Func();script2Func();script3Func();});
实例2:
$LAB.script({ src:"script1.js", type:"text/javascript"}).script("script2.js").script("script3.js").wait(function(){// 等待所有script加载完再执行这个代码块 script1Func();script2Func();script3Func();});
实例3:
$LAB.script("script1.js","script2.js","script3.js").wait(function(){// 等待所有script加载完再执行这个代码块 script1Func();script2Func();script3Func();});
实例4:
$LAB.script(["script1.js","script2.js"],"script3.js").wait(function(){// 等待所有script加载完再执行这个代码块 script1Func();script2Func();script3Func();});
实例5:
$LAB.script("script1.js").wait() // 空的wait()只是确保script1在其他代码之前被执行.script("script2.js") // script2 和 script3 依赖于 script1.script("script3.js").wait() // 但是script2 和 script3 并不互相依赖,可以并行下载.script("script4.js") //script4 依赖于 script1, script2 及 script3 .wait(function(){script4Func();});
实例6:
$LAB.script("script1.js") // script1, script2, and script3 之间没有依赖关系, .script("script2.js") // 所以可以任意顺序执行.script("script3.js").wait(function(){ // 如果需要,这里当然可以执行javascript函数alert("Scripts 1-3 are loaded!");}).script("script4.js") // 依赖于 script1, script2 及 script3 .wait(function(){script4Func();});
实例7:
$LAB.setOptions({AlwaysPreserveOrder:true})// 设置每个脚本之间等待.script("script1.js")// script1, script2, script3, script4 互相依赖.script("script2.js")// 并且并行下载后循序执行.script("script3.js").script("script4.js").wait(function(){script4Func();});
实例8:
$LAB.script(function(){ // `_is_IE`的值ie为true ,非ie为falseif(_is_IE){ return"ie.js"; // 如果是ie则这个js会被加载}else{ return null; //如果不是ie这个代码就会被略过 }}).script("script1.js").wait();
三、LABjs主要采用加载方式
LABjs里的动态加载脚本文件,是指页面的js脚本执行时,通过多种方法去加载外部的js(主要区别于html页面里,通过<script>标签静态加载的脚本)
动态加载脚本的方式有很多,优缺点不一,此处不赘述,有兴趣的童鞋可以参见本文末尾的参考链接 :)。
LABjs里主要使用了三种技巧,分别为Script Element、XHR Injection以及Cache Trick
首先对这三种加载方式进行简单介绍,第四部分再分析LABjs源码实现里面对着三种方式分别的使用场景
Script Element(LABjs默认采用加载方式)
最常见的脚本动态加载方式,优点很多,包括:1、实现简单 2、可跨域 3、不会阻塞其他资源的加载 等
Opera/Firefox(老版本)下:脚本执行的顺序与节点被插入页面的顺序一致
IE/Safari/Chrome下:执行顺序无法得到保证
注意:
新版本的Firefox下,脚本执行的顺序与插入页面的顺序不一定一致,但可通过将script标签的async属性设置为false来保证顺序执行
老版本的Chrome下,脚本执行的顺序与插入页面的顺序不一定一致,但可通过将script标签的async属性设置为false来保证顺序执行
XHR Injection
通过ajax请求加载脚本文件,然后再通过以下方式执行:
eval:常见方式
XHR injection:创建一个script元素,并将请加载的脚本文件的内容注入
主要限制:无法跨域
Cache Trick(强依赖于浏览器的特性实现,不推荐使用)
当你将script元素的type属性设置为浏览器不认识的值,比如"text/cache"、"text/casper"、"text/hellworld"等,不同浏览器的行为如下:
IE/Safari/Chrome(老版本)里:脚本照常加载,但不会执行,假设浏览器没有禁用缓存,加载后的脚本会被浏览器缓存起来,当需要用到的时候,只需要重新创建个script标签,将type设为正确的值,src指向之前请求的文件url即可(相当于从缓存里读文件)
Opera/Firefox:不加载
备注:
强依赖于浏览器的特性实现,有可能随着浏览器特性实现的改变而失效,不推荐使用
新版本的chrome浏览器,将script元素的type设置为非"text/javascript",不会再对脚本文件进行加载
四、LABjs里关于脚本加载采用方案的判断
忽略技术细节,通过一段伪代码来描述LABjs里面的实现,大致为:
首先判断是否对请求的脚本进行预加载(是否进行预加载的判断条件看伪代码注释);
如进行预加载,再判断浏览器是否支持真正的预加载;如支持真正的预加载,则预加载之;如否,判断请求的脚本是否跟当前页面同域,如实,采用XHR Injection,如否,采用Cache Trick;
如不进行预加载,判断浏览器支不支持script元素的async属性(见伪代码注释),如是,设置async属性,并请求脚本文件;如否,直接通过script元素加载脚本文件;
if(ifPreloadScript){ //当请求的脚本文件是否进行预加载:1、需要预加载 2、浏览器支持预加载if(supportRealPreloading){ //如果支持真正的预加载if(supportPreloadPropNatively){ //支持通过设置script标签的preload属性,实现script的预加载,以及分离加载和执行//Nicholas C. Zakas大神的美好愿望,尚未有浏览器支持:http://www.nczonline.net/blog/2011/02/14/separating-javascript-download-and-execution/script.onpreload = callback;script.newPreload = true;script.src = targetUrl;}else{script.onreadystatechange = callback; //其实就是指IE浏览器,假设指定了script元素的src属性,IE浏览器里会立即加载script.src = targetUrl; //即使script元素没有被插入页面,callback为预加载后的回调 }} else if(inSameDomain){ //非跨域,采用XHR Injection:请求的脚本与当前页面处于同一个域xhr = new XMLHttpRequest(); //由于上个判断已经将IE无情地抛弃在这个条件分支之外,所以大胆地用 new XMLHttpRequest()吧xhr.onreadystatechange = callback;xhr.open("GET",targetUrl);xhr.send();} else{ //最无奈的后招,Cache Trick,新版chromei已经不支持script.onload = callback;script.type = 'text/cache'; script.src = targetUrl;}}else{ if(canContrlExecutionOrderByAsync){ //如果能够通过script元素的async属性来强制并行加载的脚本顺序执行//kyle大神着力推进的提案,目前已被html5小组接受并放入草案:http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order#My_Solutionscript.onload = callback;script.async = false; //将script元素的async设为false,可以保证script的执行顺序与请求顺序保持一致script.src = targetUrl;} else{script.onload = callback;script.src = targetUrl; }
}
实际上,当你在页面创建一个img节点,并将其src指向一个脚本文件,在部分浏览器里同样能够起到文件预加载的作用,那么LABjs的作者是不是没有想到这一点呢?
不少LABjs的使用者都向kyle提过上面这个问题,key表示:在现有加载策略已经能够满足需求的情况下,不想让LABjs的设计变得更复杂了(非原话)
写在后面
此处仅仅简单对LABjs的作用、用法以及内部实现简单介绍了下,关于内部具体源代码实现的分析,留待下一篇文章
如有错漏,请指出 ,如有问题,欢迎回复以及邮件进一步交流 :)
转载于:https://my.oschina.net/wolfx/blog/617376
JS异步加载库LABjs简易说明相关推荐
- 知识点讲解五:处理js异步加载问题
文章目录 前言 环境 代码思路 原代码 前言 在新闻网站中大多采用的是异步加载模式,新闻条目会随滚动条的滚动而逐渐加载.当爬虫访问这类网站时得到的HTML数据仅仅是我们看到的页面数据,只有当我们向下滚 ...
- 【前端】JS异步加载
文章目录 为什么要异步加载 如何实现异步加载 参考 为什么要异步加载 两个原因其实是一个意思. 原因1: JS是单线程的语言,它会同步的执行代码,从上往下执行 但是,一旦网络不好,或要加载的js文件过 ...
- turn.js异步加载实现翻书效果
<div class="m-art-cont"><script type="text/javascript" src="/Runti ...
- 实现JS异步加载的三种方法
一.为什么要写异步加载: ①js加载本身是属于同步加载的,加载js文件会阻塞文档,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作.但是有些工具方法需要按需加载,有一些工具js文件它是不 ...
- JS 异步加载js的三种方案
js文件同步加载的缺点: 页面的js文件一般是同步加载,加载到js文件会阻断html和css的加载,要等到js文件加载完毕,才能继续向下执行,因为js文件可能会操作html和css:但有些js文件不会 ...
- js延迟加载、js异步加载
1.js延迟加载 (1)js延迟加载是js性能优化的一种方式 (2)作用:为了提高网页的加载速度 (3)原理:等网页加载完成之后再加载js文件 ··需要优化的原 ...
- yepnope.js 异步加载资源文件
yepnope.js是一个能够根据输入条件来选择性异步加载资源文件的js脚本,可以在页面上仅加载用户需要的js/css. yepnope的优点: 可以同时处理javascript以及css 能够按条件 ...
- JS异步加载及解决方式
1.js中的同步加载和异步加载有什么不同? javascript语言是单线程机制.所谓单线程就是按次序执行,执行完一个任务再执行下一个. 对于浏览器来说,也就是无法在渲染页面的同时执行代码. 同步加载 ...
- turn.js 异步加载实现翻书效果
1.阅读翻书js /*** 电子翻书*/ //var width = 1080; //var height = 1680;var width = "10rem"; var heig ...
最新文章
- 学习UI设计能做什么
- PHP经验总结 - 开发技巧分享
- 一款研发管理软件的对象标签介绍
- ios 查看同文件名_实战恢复cisco 2950交换机的IOS
- mysql 事务sqlserver_SQLServer数据库:事务与隔离级别实例讲解
- rsync+inotify实现服务器之间文件实时同步
- 计算机考研310分什么水平,知乎工学考研310是什么水平
- pandas中DataFrame对象to_csv()方法中的encoding参数
- IDEA插件下载地址
- android 闪屏图片,Android的闪屏图像尺寸,以适应所有设备Android的闪屏图像尺寸,以适应所有设备(Andro...
- 语音识别—声学模型训练(前向-后向算法)
- DTI脑网络构建 详细介绍处理过程以及PANDA的使用
- CMOS反相器设计与仿真
- springboot 实现redis高并发抢票服务
- 中国娱记的鼻祖留心shuo新浪博客
- python100个常用函数
- 美国西北大学新系统在智力测试中超越75%民众,人类的推理能力也不及AI了?...
- 使用Audio Mixer分别控制音效
- 番外 01 - 开源许可证在国内等于格式合同
- 求职之路(2015南京站拿到百度、美团、趋势科技、华为offer)