最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳談LABJS按需動(dòng)態(tài)加載js文件

 更新時(shí)間:2015年05月07日 12:09:45   投稿:hebedich  
為了提高頁(yè)面的打開(kāi)和加載速度,我們經(jīng)常把JS文件放在頁(yè)面的尾部,但是有些JS必須放在頁(yè)面前面,這樣就會(huì)增加頁(yè)面的加載時(shí)間;于是出現(xiàn)了按需動(dòng)態(tài)加載的概念,這個(gè)概念就是當(dāng)頁(yè)面需要用到這個(gè)JS文件或者CSS渲染文件的時(shí)候,在去請(qǐng)求這些文件,這樣就節(jié)省了頁(yè)面的加載時(shí)間

LABjs 是一個(gè)很小的 JavaScript 工具,用來(lái)根據(jù)需要加載 JavaScript 文件,通過(guò)使用該工具可以提升頁(yè)面的性能,避免加載不需用到的 JavaScript 文件,可以實(shí)現(xiàn)動(dòng)態(tài)并行加載腳本文件,以及管理加載腳本文件的執(zhí)行順序。

簡(jiǎn)單示例

$LAB
.script("script1.js", "script2.js", "script3.js")
.block(function(){
  // wait for all to load, then do something
  script1Func();
  script2Func();
  script3Func();
});

介紹下LABJS的幾個(gè)實(shí)例:
實(shí)例1:

$LAB
  .script("script1.js")
  .script("script2.js")
  .script("script3.js")
  .wait(function(){ // 等待所有script加載完再執(zhí)行這個(gè)代碼塊
    script1Func();
    script2Func();
    script3Func();
  });

實(shí)例2:

$LAB 
  .script({ src: "script1.js", type: "text/javascript" })
  .script("script2.js")
  .script("script3.js")
  .wait(function(){ // 等待所有script加載完再執(zhí)行這個(gè)代碼塊
    script1Func();
    script2Func();
    script3Func();
  });

實(shí)例3:

$LAB
  .script("script1.js", "script2.js", "script3.js")
  .wait(function(){ // 等待所有script加載完再執(zhí)行這個(gè)代碼塊
    script1Func();
    script2Func();
    script3Func();
  });

實(shí)例4:

$LAB
  .script( [ "script1.js", "script2.js" ], "script3.js")
  .wait(function(){ // 等待所有script加載完再執(zhí)行這個(gè)代碼塊
    script1Func();
    script2Func();
    script3Func();
  });

實(shí)例5:

$LAB
  .script("script1.js").wait() // 空的wait()只是確保script1在其他代碼之前被執(zhí)行
  .script("script2.js") // script2 和 script3 依賴(lài)于 script1
  .script("script3.js").wait() // 但是script2 和 script3 并不互相依賴(lài),可以并行下載
  .script("script4.js") // script4 依賴(lài)于 script1, script2 及 script3
  .wait(function(){script4Func();});

實(shí)例6:

$LAB
  .script("script1.js") // script1, script2, and script3 之間沒(méi)有依賴(lài)關(guān)系,
  .script("script2.js") // 所以可以任意順序執(zhí)行
  .script("script3.js")
  .wait(function(){ // 如果需要,這里當(dāng)然可以執(zhí)行javascript函數(shù)
    alert("Scripts 1-3 are loaded!");
  })
  .script("script4.js") // 依賴(lài)于 script1, script2 及 script3
  .wait(function(){script4Func();});

實(shí)例7:

$LAB
  .setOptions({AlwaysPreserveOrder:true}) // 設(shè)置每個(gè)腳本之間等待
  .script("script1.js") // script1, script2, script3, script4 互相依賴(lài)
  .script("script2.js") // 并且并行下載后循序執(zhí)行
  .script("script3.js")
  .script("script4.js")
  .wait(function(){script4Func();});

實(shí)例8:

$LAB
  .script(function(){
    // `_is_IE`的值ie為true ,非ie為false
    if (_is_IE) {
      return "ie.js"; // 如果是ie則這個(gè)js會(huì)被加載
    }
    else {
      return null; //如果不是ie這個(gè)代碼就會(huì)被略過(guò)
    }
  })
  .script("script1.js")
  .wait();

LABjs加載方式

LABjs里的動(dòng)態(tài)加載腳本文件,是指頁(yè)面的js腳本執(zhí)行時(shí),通過(guò)多種方法去加載外部的js(主要區(qū)別于html頁(yè)面里,通過(guò)<script>標(biāo)簽靜態(tài)加載的腳本)

動(dòng)態(tài)加載腳本的方式有很多,優(yōu)缺點(diǎn)不一,此處不贅述,有興趣的童鞋可以參見(jiàn)本文末尾的參考鏈接 :)。

LABjs里主要使用了三種技巧,分別為Script Element、XHR Injection以及Cache Trick

首先對(duì)這三種加載方式進(jìn)行簡(jiǎn)單介紹,第四部分再分析LABjs源碼實(shí)現(xiàn)里面對(duì)著三種方式分別的使用場(chǎng)景

Script Element(LABjs默認(rèn)采用加載方式)

最常見(jiàn)的腳本動(dòng)態(tài)加載方式,優(yōu)點(diǎn)很多,包括:1、實(shí)現(xiàn)簡(jiǎn)單 2、可跨域 3、不會(huì)阻塞其他資源的加載 等

Opera/Firefox(老版本)下:腳本執(zhí)行的順序與節(jié)點(diǎn)被插入頁(yè)面的順序一致

IE/Safari/Chrome下:執(zhí)行順序無(wú)法得到保證

注意:

新版本的Firefox下,腳本執(zhí)行的順序與插入頁(yè)面的順序不一定一致,但可通過(guò)將script標(biāo)簽的async屬性設(shè)置為false來(lái)保證順序執(zhí)行

老版本的Chrome下,腳本執(zhí)行的順序與插入頁(yè)面的順序不一定一致,但可通過(guò)將script標(biāo)簽的async屬性設(shè)置為false來(lái)保證順序執(zhí)行

XHR Injection
通過(guò)ajax請(qǐng)求加載腳本文件,然后再通過(guò)以下方式執(zhí)行:
eval:常見(jiàn)方式
XHR injection:創(chuàng)建一個(gè)script元素,并將請(qǐng)加載的腳本文件的內(nèi)容注入
主要限制:無(wú)法跨域
Cache Trick(強(qiáng)依賴(lài)于瀏覽器的特性實(shí)現(xiàn),不推薦使用)
當(dāng)你將script元素的type屬性設(shè)置為瀏覽器不認(rèn)識(shí)的值,比如”text/cache”、”text/casper”、”text/hellworld”等,不同瀏覽器的行為如下:
IE/Safari/Chrome(老版本)里:腳本照常加載,但不會(huì)執(zhí)行,假設(shè)瀏覽器沒(méi)有禁用緩存,加載后的腳本會(huì)被瀏覽器緩存起來(lái),當(dāng)需要用到 的時(shí)候,只需要重新創(chuàng)建個(gè)script標(biāo)簽,將type設(shè)為正確的值,src指向之前請(qǐng)求的文件url即可(相當(dāng)于從緩存里讀文件)
Opera/Firefox:不加載
備注:
強(qiáng)依賴(lài)于瀏覽器的特性實(shí)現(xiàn),有可能隨著瀏覽器特性實(shí)現(xiàn)的改變而失效,不推薦使用
新版本的chrome瀏覽器,將script元素的type設(shè)置為非”text/javascript”,不會(huì)再對(duì)腳本文件進(jìn)行加載。

LABjs里關(guān)于腳本加載采用方案的判斷

忽略技術(shù)細(xì)節(jié),通過(guò)一段偽代碼來(lái)描述LABjs里面的實(shí)現(xiàn),大致為:
首先判斷是否對(duì)請(qǐng)求的腳本進(jìn)行預(yù)加載(是否進(jìn)行預(yù)加載的判斷條件看偽代碼注釋?zhuān)?br /> 如進(jìn)行預(yù)加載,再判斷瀏覽器是否支持真正的預(yù)加載;如支持真正的預(yù)加載,則預(yù)加載之;如否,判斷請(qǐng)求的腳本是否跟當(dāng)前頁(yè)面同域,如實(shí),采用XHR Injection,如否,采用Cache Trick;
如不進(jìn)行預(yù)加載,判斷瀏覽器支不支持script元素的async屬性(見(jiàn)偽代碼注釋?zhuān)缡?,設(shè)置async屬性,并請(qǐng)求腳本文件;如否,直接通過(guò)script元素加載腳本文件;
 

if(ifPreloadScript){  //當(dāng)請(qǐng)求的腳本文件是否進(jìn)行預(yù)加載:1、需要預(yù)加載 2、瀏覽器支持預(yù)加載
  if(supportRealPreloading){  //如果支持真正的預(yù)加載
    if(supportPreloadPropNatively){  //支持通過(guò)設(shè)置script標(biāo)簽的preload屬性,實(shí)現(xiàn)script的預(yù)加載,以及分離加載和執(zhí)行
                    //Nicholas C. Zakas大神的美好愿望,尚未有瀏覽器支持:/blog/2011/02/14/separating-javascript-download-and-execution/
      script.onpreload = callback;
      script.newPreload = true;
      script.src = targetUrl;
    }else{
      script.onreadystatechange = callback;  //其實(shí)就是指IE瀏覽器,假設(shè)指定了script元素的src屬性,IE瀏覽器里會(huì)立即加載
      script.src = targetUrl;  //即使script元素沒(méi)有被插入頁(yè)面,callback為預(yù)加載后的回調(diào)
    }
  }
  else if(inSameDomain){  //非跨域,采用XHR Injection:請(qǐng)求的腳本與當(dāng)前頁(yè)面處于同一個(gè)域
    xhr = new XMLHttpRequest();  //由于上個(gè)判斷已經(jīng)將IE無(wú)情地拋棄在這個(gè)條件分支之外,所以大膽地用 new XMLHttpRequest()吧
    xhr.onreadystatechange = callback;
    xhr.open("GET",targetUrl);
    xhr.send();
  }
  else{  //最無(wú)奈的后招,Cache Trick,新版chromei已經(jīng)不支持
    script.onload = callback;
    script.type = 'text/cache';  
    script.src = targetUrl;
  }
}else{
  if(canContrlExecutionOrderByAsync){  //如果能夠通過(guò)script元素的async屬性來(lái)強(qiáng)制并行加載的腳本順序執(zhí)行
                    //kyle大神著力推進(jìn)的提案,目前已被html5小組接受并放入草案:/Dynamic_Script_Execution_Order#My_Solution
    script.onload = callback;
    script.async = false;  //將script元素的async設(shè)為false,可以保證script的執(zhí)行順序與請(qǐng)求順序保持一致
    script.src = targetUrl;
  }
  else{
    script.onload = callback;
    script.src = targetUrl;  
  }
}

實(shí)際上,當(dāng)你在頁(yè)面創(chuàng)建一個(gè)img節(jié)點(diǎn),并將其src指向一個(gè)腳本文件,在部分瀏覽器里同樣能夠起到文件預(yù)加載的作用,那么LABjs的作者是不是沒(méi)有想到這一點(diǎn)呢?

相關(guān)文章

最新評(píng)論

杭锦旗| 若尔盖县| 榆林市| 南昌市| 醴陵市| 勐海县| 新干县| 定州市| 双桥区| 历史| 巴林右旗| 钦州市| 仁怀市| 赫章县| 汉阴县| 德阳市| 防城港市| 东阳市| 探索| 万宁市| 图们市| 集贤县| 康平县| 沙雅县| 荆门市| 崇信县| 桦南县| 静海县| 镇江市| 岳池县| 扎鲁特旗| 贵港市| 和硕县| 西乌珠穆沁旗| 洮南市| 大新县| 简阳市| 三河市| 公安县| 龙门县| 全州县|