LABJS浅析

来源:http://www.cnblogs.com/chyingp/archive/2012/10/17/2726898.html

一、关于LABjs的简单介绍

作者:Kyle Simpson

作用:动态并行加载脚本文件 以及 管理加载脚本文件的执行顺序

官网:http://www.labjs.com/

二、关于LABjs的使用

实例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为false
        if(_is_IE){
            return"ie.js";    // 如果是ie则这个js会被加载
        }else{
            return null;    //如果不是ie这个代码就会被略过
        }
    })
    .script("script1.js")
  .wait();

三、LABjs主要采用加载方式

LABjs里的动态加载脚本文件,是指页面的js脚本执行时,通过多种方法去加载外部的js(主要区别于html页面里,通过<script>标签静态加载的脚本)

动态加载脚本的方式有很多,优缺点不一,此处不赘述,有兴趣的童鞋可以参见本文末尾的参考链接 :)。

LABjs里主要使用了三种技巧,分别为Script ElementXHR 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_Solution
        script.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的设计变得更复杂了(非原话)

时间: 2024-10-10 01:26:35

LABJS浅析的相关文章

LABjs学习(一)之无阻塞动态并行加载脚本文件以及管理执行顺序

什么是LABjs LABjs是一个动态的脚本加载器,LABjs的定义特性是能够在浏览器允许的范围内以最快的速度并行加载所有JavaScript文件,但是如果文件之间存在依赖关系,则可以选择确保正确的执行顺序. 总计来说就是:动态并行加载脚本文件以及管理加载脚本文件的执行顺序 使用方法 $LAB对象替代了<script>标签,然后.script()方法表示加载Javascript文件,不带参数的.wait()方法表示立即运行刚才加载的Javascript文件,带参数的.wait()方法也是立即运

LABJS源码浅析

一.关于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.

JavaScript文件加载器LABjs API详解

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

Python之encode与decode浅析

 Python之encode与decode浅析 在 python 源代码文件中,如果你有用到非ASCII字符,则需要在文件头部进行字符编码的声明,声明如下: # code: UTF-8 因为python 只检查 #.coding 和编码字符串,为了美观等原因可以如下写法: #-*-coding:utf-8-*- 常见编码介绍: GB2312编码:适用于汉字处理.汉字通信等系统之间的信息交换. GBK编码:是汉字编码标准之一,是在 GB2312-80 标准基础上的内码扩展规范,使用了双字节编码.

浅析PHP的开源产品二次开发的基本要求

浅析PHP的开源产品二次开发的基本要求 第一, 基本要求:HTML(必须要非常熟悉),PHP(能看懂代码,能写一些小系统,如:留言板,小型CMS),Mysql(至少会一种数据库),Javascript(能看懂,能改现成的一些代码),Div+Css(能进行界面的调整,明白CSS是怎么使用的) 第二, 熟悉开源产品的使用,比如 Dedecms,你要知道怎么登录,怎么新建栏目,怎么添加文章,模板标签的使用方法,模型的概念和使用方法等等一些功能 第三, 要熟悉这个开源产品的数据库结构,还要理解里面核心文

word-break|overflow-wrap|word-wrap——CSS英文断句浅析

---恢复内容开始--- word-break|overflow-wrap|word-wrap--CSS英文断句浅析 一 问题引入 今天在再次学习 overflow 属性的时候,查看效果时,看到如下结果,内容在 div 中国换行了,可是两个 P 元素的内容并没有换行,搜索一番没有找到系统的答案,截图到群里请教大神,才知道是英文断句的问题,但是还是不太明白.之前没有遇到这种情况,为了彻底搞清楚,英文断句,又开始学习英文断句到底是怎么回事. 二 换行 每种语言里都有换行,就中文而言,我们最小语言单位

浅析vanish

浅析 VANISH --一种cache 第一部分:理解vanish的准备工作 1.对CDN的小剖析 CDN  content  delivery  network  内容分发(推送)网络,是在现有的Internet中增加一层新的网络架构,将网络内容发布到最接近用户的网络边缘(边缘服务器),使用户最近取得所需内容,解决网络拥挤状态,提高用户访问网站的速度. CDN网络架构主要有两部分组成,中心和边缘两部分,中心指CDN网管中心和DNS重定向解析中心,负责全局负载均衡.边缘主要指异地节点,CDN分发

健康,home? [java的内存浅析]

健康,home? [java的内存浅析] 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 乐观上上,how can other kno u,u r yourself!I must be strong and carry on. -泥沙砖瓦浆木匠 一.闲谈下 201407月记着那时候身体垮了下来,呵呵.想说,对自己的说,也是对大家的负责吧.那时候胸疼胸闷,然后几乎累垮了,我还坚持了一星期,那一星期真的迷迷糊糊.完全不能

Mysql查询优化器浅析

--Mysql查询优化器浅析 -----------------------------2014/06/11 1 定义 Mysql查询优化器的工作是为查询语句选择合适的执行路径.查询优化器的代码一般是经常变动的,这和存储引擎不太一样.因此,需要理解最新版本的查询优化器是如何组织的,请参考相应的源代码.整体而言,优化器有很多相同性,对mysql一个版本的优化器做到整体掌握,理解起mysql新版本以及其他数据库的优化器都是类似的. 优化器会对查询语句进行转化,转化等价的查询语句.举个例子,优化器会将