Home  >  Article  >  Web Front-end  >  Discuss in detail LABJS dynamic loading of js files on demand_javascript skills

Discuss in detail LABJS dynamic loading of js files on demand_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:00:271657browse

LABjs is a small JavaScript tool that is used to load JavaScript files as needed. By using this tool, you can improve the performance of the page, avoid loading unnecessary JavaScript files, and realize dynamic parallel loading of script files and management. The execution order of loading script files.

Simple example

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

Introducing several examples of LABJS:
Example 1:

$LAB
  .script("script1.js")
  .script("script2.js")
  .script("script3.js")
  .wait(function(){ // 等待所有script加载完再执行这个代码块
    script1Func();
    script2Func();
    script3Func();
  });

Example 2:

$LAB 
  .script({ src: "script1.js", type: "text/javascript" })
  .script("script2.js")
  .script("script3.js")
  .wait(function(){ // 等待所有script加载完再执行这个代码块
    script1Func();
    script2Func();
    script3Func();
  });

Example 3:

$LAB
  .script("script1.js", "script2.js", "script3.js")
  .wait(function(){ // 等待所有script加载完再执行这个代码块
    script1Func();
    script2Func();
    script3Func();
  });

Example 4:

$LAB
  .script( [ "script1.js", "script2.js" ], "script3.js")
  .wait(function(){ // 等待所有script加载完再执行这个代码块
    script1Func();
    script2Func();
    script3Func();
  });

Example 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();});

Example 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();});

Example 7:

$LAB
  .setOptions({AlwaysPreserveOrder:true}) // 设置每个脚本之间等待
  .script("script1.js") // script1, script2, script3, script4 互相依赖
  .script("script2.js") // 并且并行下载后循序执行
  .script("script3.js")
  .script("script4.js")
  .wait(function(){script4Func();});

Example 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 loading method

Dynamic loading of script files in LABjs refers to loading external js through various methods when the js script of the page is executed (mainly different from scripts statically loaded through the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag in html pages)

There are many ways to dynamically load scripts, with different advantages and disadvantages. I won’t go into details here. Interested children can refer to the reference link at the end of this article :).

There are three main techniques used in LABjs, namely Script Element, XHR Injection and Cache Trick

Firstly, we will give a brief introduction to these three loading methods. In the fourth part, we will analyze the usage scenarios of the three methods in LABjs source code implementation

Script Element (LABjs uses the loading method by default)

The most common method of dynamically loading scripts has many advantages, including: 1. Simple implementation 2. Can be cross-domain 3. Will not block the loading of other resources, etc.

Under Opera/Firefox (old version): the order of script execution is consistent with the order in which nodes are inserted into the page

Under IE/Safari/Chrome: The execution order cannot be guaranteed

Note:

Under the new version of Firefox, the order of script execution is not necessarily the same as the order of insertion into the page, but the order of execution can be guaranteed by setting the async attribute of the script tag to false

Under the old version of Chrome, the order of script execution is not necessarily the same as the order of insertion into the page, but the order of execution can be guaranteed by setting the async attribute of the script tag to false

XHR Injection
Load the script file via ajax request and then execute it via:
eval: common method
XHR injection: Create a script element and inject the content of the loaded script file into
Main limitation: cannot cross domain
Cache Trick (strongly dependent on browser feature implementation, not recommended)
When you set the type attribute of the script element to a value that the browser does not recognize, such as "text/cache", "text/casper", "text/hellworld", etc., the behavior of different browsers is as follows:
In IE/Safari/Chrome (old version): the script is loaded as usual, but will not be executed. Assuming that the browser does not disable caching, the loaded script will be cached by the browser. When it is needed, you only need to recreate it. script tag, set type to the correct value, and src points to the previously requested file URL (equivalent to reading the file from the cache)
Opera/Firefox: Not loading
Note:
It is strongly dependent on the browser's feature implementation and may become invalid as the browser's feature implementation changes. It is not recommended to use
The new version of the Chrome browser sets the type of the script element to something other than "text/javascript" and will no longer load the script file.

Judgment on script loading options in LABjs

Ignore the technical details and describe the implementation in LABjs through a piece of pseudo code, which is roughly:
First, determine whether to preload the requested script (see pseudo code comments for the conditions for preloading);
If preloading is performed, then determine whether the browser supports true preloading; if it supports true preloading, preload it; if not, determine whether the requested script is in the same domain as the current page. If so, use XHR Injection. If not, , using Cache Trick;
If preloading is not performed, determine whether the browser supports the async attribute of the script element (see pseudo code comments). If so, set the async attribute and request the script file; if not, load the script file directly through the script element;

if(ifPreloadScript){  //当请求的脚本文件是否进行预加载:1、需要预加载 2、浏览器支持预加载
  if(supportRealPreloading){  //如果支持真正的预加载
    if(supportPreloadPropNatively){  //支持通过设置script标签的preload属性,实现script的预加载,以及分离加载和执行
                    //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;  //其实就是指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小组接受并放入草案:/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;  
  }
}

In fact, when you create an img node on the page and point its src to a script file, it can also play the role of file preloading in some browsers. Did the author of LABjs not think of this? ?

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn