在《高性能JavaScript》一书中提到了LABjs这个用来加载JavaScript文件的类库,LABjs是Loading And Blocking JavaScript的缩写,顾名思义,加载和阻塞JavaScript,而它的API script()和wait()则优雅地实现了这两个功能,我在高性能JavaScript 加载和执行一文中也简单讲解了这两个核心API的用法。当然,LABjs还有更多的API,本文用实例讲解下LABjs其他API。

$LAB.setGlobalDefaults() & $LAB.setOptions()

  两者所能设置的参数完全一致,不同的是,前者是全局设置,作用在所有的$LAB链上;后者出现在某条链的开头位置(后面接script()、wait()等),该设置只作用在这条链上。该参数可以是一个包含多个键值对的对象。

  • AlwaysPreserveOrder

  一个布尔值(默认false),如果设置为true,则每个script()后都会默认设置一个wait(),使得链上的脚本一个个执行。

$LAB
  .setOptions({AlwaysPreserveOrder:true}) // tells this chain to implicitly "wait" on
                                          // execution (not loading) between each script
  .script("script1.js") // script1, script2, script3, and script4 *DO* depend on each
  .script("script2.js") // other, and will execute serially in order after all 4 have have
  .script("script3.js") // loaded in parallel
  .script("script4.js")
  .wait(function(){script4Func();});
  • UseLocalXHR

  一个布尔值(默认true),如果是true的话,LABjs会用XHR Ajax去预加载同域的脚本文件。值得注意的是,只应用在老式的Webkit浏览器(那些既不能使用ordered-async也不能实现真正的预加载的浏览器),而且同域的情况下,该设置才起效(不然直接无视)

  • CacheBust & AllowDuplicates

  LABjs对于缓存有一些奇怪的处理(关于缓存,可以参考我前面的一篇文章浏览器缓存机制浅析),比如如下代码:

$LAB.script('index.js');

  很简单对吧?第一次载入,没有任何问题,HTTP200从server端下载。但是f5后:

  (2015-8-3 这个问题有点诡异,有时HTTP304,有时HTTP200from cache 我也在github上询问了作者 LABjs reads from cache when f5,回复的大概意思是cache和labjs没有任何关系,只和服务器和浏览器设置有关)

  居然是从缓存读取的!这就是说服务端的改动,对它不起效果!而通常情况下f5后是会向服务器发送请求的,如果服务端文件没有修改返回HTTP304读取缓存,如果修改了文件直接load新的。针对这个问题我们可以使用CacheBust选项:

$LAB.setGlobalDefaults({CacheBust: true})
$LAB.script('index.js');

  这样就能保证每次都从服务端读取文件(从不读取缓存)。

  还有一个问题,对于几个相同的请求,LABjs默认只会执行一次:

$LAB.script('index.js').script('index.js');
$LAB.script('index.js');

  实际上index.js这个文件只执行了一次!如果index.js里的代码是打印hello world,也就是说只会被打印一次。如何做到能打印三次?用AllowDuplicates:

$LAB.setGlobalDefaults({AllowDuplicates: true})
$LAB.script('index.js').script('index.js');
$LAB.script('index.js');

  实际上上面的代码,尽管会执行三次index.js,但是请求只有一次,其他两个都是缓存读取,而且如前面所说,如果服务端修改了,也会从缓存读取,这太可怕了。所以AllowDuplicates可以配合CacheBust使用:

$LAB.setGlobalDefaults({AllowDuplicates: true, CacheBust: true})
$LAB.script('index.js').script('index.js');
$LAB.script('index.js');

  其实就是带了一串代表请求唯一的字符串,这在ajax请求中很常见。

  • BasePath

  一个字符串(默认空串),会将这个字符串加在每个script()里的URL的最前面。

  • Debug

  一个布尔值(默认false),如果开启debug选项的话,会在控制台打印信息,需要注意的是,只有使用了LAB-debug.min.js或者LAB.src.js该选项才work。

$LAB.script() & $LAB.wait()

  script()里的参数可以是很多形式,比如字符串(文件的相对路径或者绝对路径)、对象(src、type、charset src必须)、数组或者方法(或者前者们的组合),更多demo可以参考Example 8 below。前三者很好理解,这里简单提下参数为function的情况,当script()里的参数是个匿名的function的时候,该function会立即执行,它可以return一个值,而该值必须是以上说的string、object或者array形式,相当于给该script()赋值了。

$LAB
  .script(function(){
    // assuming `_is_IE` defined by host page as true in IE and false in other browsers
    if (_is_IE) {
      return "ie.js"; // only if in IE, this script will be loaded
    }
    else {
      return null; // if not in IE, this script call will effectively be ignored
    }
  })
  .script("script1.js")
  .wait();

$LAB.queueScript() & $LAB.queueWait() & $LAB.runQueue() & $LAB.sandbox()

  script()和wait()会使得脚本立即执行(除非设置定时器),但是queueScript()和queueWait()能使得脚本在任意时刻执行,执行的时候带上runQueue()就行了。

var a = $LAB.queueScript('index.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  a.runQueue()
}, 1000);

  如上脚本就能在1000ms后执行,这样的效果貌似script()配合定时器也能实现,但是在未来某一不确定时刻执行就不行了(比如说一段指定代码后)。如果有两个链要在未来某时刻执行呢?

var a = $LAB.queueScript('index.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  a.runQueue()
}, 1000);

var b = $LAB.queueScript('index2.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  b.runQueue()
}, 2000);

  如上代码并没能得到预想的结果(实际上1000ms后一起输出),这时就需要用sandbox()创建一个新的实例。

var a = $LAB.queueScript('index.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  a.runQueue()
}, 1000);

var b = $LAB.sandbox().queueScript('index2.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  b.runQueue()
}, 2000);

$LAB.noConflict()

  使用noConflict()会将当前版本的LABjs回滚到旧的版本。(2015-08-04 这个解释应该是错的)

  read more from LAB documentation

JavaScript文件加载器LABjs API详解的更多相关文章

  1. Javascript文件加载:LABjs和RequireJS

    传统上,加载Javascript文件都是使用<script>标签. 就像下面这样: <script type="text/javascript" src=&quo ...

  2. 小矮人Javascript模块加载器

    https://github.com/miniflycn/webkit-dwarf 短小精悍的webkit浏览器Javascript模块加载器 Why 我们有许多仅基于webkit浏览器开发的应用 无 ...

  3. RequireJS 是一个JavaScript模块加载器

    RequireJS 是一个JavaScript模块加载器.它非常适合在浏览器中使用, 它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 就像 Rhino and Node. 使用RequireJ ...

  4. javascript文件加载模式与加载方法

    加载方式 形象图像化方法,见 http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html 1. script标签, ...

  5. 高性能javascript 文件加载阻塞

    高性能javascript   javascript脚本执行过程中会中断页面加载,直到脚本执行完毕,此操作阻塞了页面加载,造成性能问题. 脚本位置和加载顺序:如果将脚本放在head内,那么再脚本执行完 ...

  6. js文件加载太慢,JavaScript文件加载加速

    原文出自:https://blog.csdn.net/seesun2012 js脚本加载太慢,JavaScript脚本加载加速(亲测有效) 测试背景: JS文件大小:6.1kB 传统形式加载js文件: ...

  7. 实现一个JavaScript模块化加载器

    对任何程序,都存在一个规模的问题,起初我们使用函数来组织不同的模块,但是随着应用规模的不断变大,简单的重构函数并不能顺利的解决问题.尤其对JavaScript程序而言,模块化有助于解决我们在前端开发中 ...

  8. ELF文件的加载过程(load_elf_binary函数详解)--Linux进程的管理与调度(十三)

    加载和动态链接 从编译/链接和运行的角度看,应用程序和库程序的连接有两种方式. 一种是固定的.静态的连接,就是把需要用到的库函数的目标代码(二进制)代码从程序库中抽取出来,链接进应用软件的目标映像中: ...

  9. [转]微擎load()文件加载器

    本文转自:https://blog.csdn.net/qq_32737755/article/details/78124534 微擎中加载文件需要用到 load() 在官网找到官方对load()的解释 ...

随机推荐

  1. mysql源码解读之事务提交过程(二)

    上一篇文章我介绍了在关闭binlog的情况下,事务提交的大概流程.之所以关闭binlog,是因为开启binlog后事务提交流程会变成两阶段提交,这里的两阶段提交并不涉及分布式事务,当然mysql把它称 ...

  2. Oracle Data Provider for .NET

    官方地址: http://www.oracle.com/technetwork/topics/dotnet/index-085163.html 终于有正式版了.不用装客户端,又小,确实好.

  3. 使用For XML PATH 会影响Cross Apply 返回

    昨天在写语句的时候,遇到了一个现象,其实就是使用 Cross Apply做一个拼接字符串的而已.比如 CREATE TABLE GoodsCatalog (ID INT, Name )) CREATE ...

  4. Js 关于console 在IE 下的兼容问题

    程序员在开发代码的过程中,使用console作为调试代码过程的一种手段. 发布到测试生产环境,发现IE8 出现加载错误.使用开发者工具调试,发现可以绕过问题. 通过网络搜索和在项目中进行修正. 以下办 ...

  5. ELF Format 笔记(八)—— 符号的类型和属性(st_info)

    我是天空里的一片云,偶尔投影在你的波心,你不必讶异,更无须欢喜,在转瞬间消灭了踪影.你我相逢在黑夜的海上,你有你的,我有我的,方向:你记得也好,最好你忘掉,在这交会时互放的光亮! —— 徐志摩·偶然 ...

  6. 理解 Linux 网络栈(3):QEMU/KVM + VxLAN 环境下的 Segmentation Offloading 技术(发送端)

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

  7. plain framework 1 参考手册 入门指引之简介

    简介 简介 能做什么? LINUX WINDOWS 简介 简约框架(plain framework)是一款基于C/C++开发的,跨平台(windows/linux)应用的基础框架,开发者可以利用此框架 ...

  8. ASP.NET执行模型之IIS服务器处理流程

    之前在网上看过很多对这方面的讲解,但个人觉得看下来过于 "深奥",不容易理解,所以想用更简单的方式进行阐述,便于理解. 本次我们重点分析用户请求到页面呈现过程中Web服务器的处理过 ...

  9. Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]

    题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...

  10. string、math类、random随机数、datetime、异常保护

    今天讲的知识点比较多,比较杂,以至于现在脑子里还有点乱,慢慢来吧... string (1)string.length; (获得你string字符串的长度) (2)a = a.Trim(); 重新赋值 ...