Labjs analysis http://labjs.com/documentation.php#queuescript

Source: Internet
Author: User

As the web page becomes more complex, more and more JavaScript will be used on the page. It is obviously not a good idea to include all the Javascript packages that may be used on the page at one time, as a result, various methods of loading JavaScript on demand are becoming increasingly popular. labjs is such an interesting project. At present, many websites, including Twitter, are labjs users. The following will analyze the implementation principles of labjs 1.0.4.

Due to the limited length, the Instructions on labjs usage will not be written here. If you need it, please refer to its official documentation.

The so-called dynamic loading of JS refers to the execution of some JS on the page, these JS resources dynamically load external JS (sometimes some module functions that have been defined on the execution page ).

There are several ways to load external JS:

Method Description
Xhr eval Obtain through AjaxCodeAnd run the code in eval mode.
Xhr Injection Obtain the Code through Ajax, create a script element on the page, and inject the code obtained by Ajax.
Script in IFRAME Load JS through IFRAME.
Script Dom Element Use JavaScript to dynamically create a script Dom element and set its src attribute.
Script defer/async Strictly speaking, this is not a method for dynamically loading external scripts, but the defer or async attribute of sctipt is used in many methods for dynamically loading external scripts, so it is also listed here separately. This method uses the defer attribute of the script to make the script "postponed", does not block page loading, or sets the async attribute for asynchronous execution of the script. Unfortunately, these two attributes are not supported by all browsers.
Document. Write script tag Use document. Write to write the HTML Tag script to the page.
Cache trick Use the type attribute of the custom script first (for example, <SCRIPT type = "text/Cache"...), You can even use HTML objects such as images and objects to "pre-download" JS files (download them to the browser cache) and insert them into the page when you really need to execute the corresponding code.
Web worker Some browsers support the web worker function. You can create a worker to work in the background, including loading external scripts.

Each method has its own advantages and disadvantages, such as cross-origin or blocking download of other resources (parallel download) can you manage and control the execution sequence, resources consumed, and compatibility with various browsers? (for the features of some methods, refer to here ). In fact, it is easy to load external JS dynamically to the page, but if it is possible to load multiple JS files at the same time, it is hoped that they can be downloaded as quickly as possible (Parallel download), And sometimes you may want themEnsure execution sequenceAndCompatible with mainstream browsers. To achieve this goal, labjs uses three of the above methods: script Dom element, cache trick, and xhr injection. Next, let's take a closer look at the advantages and disadvantages of these three loading JS methods.

Script Dom Element

This is the most common method. It has many advantages: it can be used to load external Js in any format across regions (external JS reconstruction is not required) does not block the download and implementation of other resources. In addition, in Firefox/opera, insert multiple JS scripts in this way. the browser will download these JS scripts in parallel (depending on the number of concurrent connections in the browser ), at the same time, they can be executed in the same order as they are inserted into the page. However, in IE (and Safari/chrome), if multiple JavaScript files are inserted simultaneously in this way, these JS files will be downloaded in parallel, but the browser cannot guarantee the execution sequence of these JS files, which will be executed first after the browser is downloaded.

As shown above,Script Dom ElementThis method is almost perfect in Firefox/opera. In fact, in these browsers,Script Dom ElementIt is also the default method used by labjs.

Cache trick

As we can see above,Script Dom ElementThis method can meet the requirements of Firefox/opera. What should I do in IE/Safari/chrome? Labjs uses a cache trick method to create a script tag and set its type to "text/CacheInsert it into the page. This trick seems to have been first proposed by @ geick of labjs. This "text/cache" is only for semantic purpose. You can set the type attribute to any value not "text/JavaScript", such as "Love/oldj.

According to the articles on labjs's blog, In the IE, Safari, and chrome browsers, if the type attribute of a script element is a value that is not recognized by a browser such as "text/cache", the browser will still normally download these JS files and trigger the onload event after the download is complete, but they will not execute these scripts. In this way, you can first load the script to the browser cache, and then create a new script element when the corresponding JS needs to be executed, set its type to the correct value. SRC is the value of the "pre-download" script just now and inserts it into the page. In this way, the script will be cached (instead of the network) instantly load the corresponding JS and execute it immediately. In this way, labjs implements script pre-loading and execution sequence Management in IE, Safari, chrome, and other browsers.

In addition, trick such as "text/cache" cannot work in Firefox/opera, because these two browsers refuse to download scripts of types they do not know, in this way, it is impossible to "pre-load. But this will not cause problems, because the two browsers can directly use the aboveScript Dom ElementTo load external scripts. (Firefox 4 tried to change the related features, and the result was a strong dissatisfaction with geode. For details, refer to here .) At the same time, this method requires the browser to support and enable caching. If the browser is disabled or does not support caching, it cannot "pre-load". What's worse, there are almost no JS methods to check whether your browser supports and enables caching.

Xhr Injection

Cache trickAlthough this method can achieve parallel download and Management of execution sequence, it is a method that relies heavily on the features of a specific browser version, if a new version of a browser changes its features on any day, this method may become invalid, and I think it is ugly. Therefore, if labjs detects that the external js to be downloaded is in the same domain as the current page and the browser is not Firefox/Opera (the execution sequence cannot be ensured to be consistent with the insertion sequence ),Xhr Injection.

Xhr InjectionThe principle is very simple. Next let's take a look at how labjs is implemented with these three methods.

The internal logic of labjs is complicated and there are many variables. However, the structure of labjs is shown in.

As you can see, there are a total of four methods available for labjs APIs, namely the setglobaldefaults () method, setoptions () method, script () method, and wait () method. Among them, script () and wait () are most commonly used (). The most important internal variable in labjs is an engine object, which is responsible for the implementation of the script () and wait () methods and maintenance of internal variables.

Engine objects mainly have the following methods: script (), wait (), loadscript (), and waitfunc (). There are also two main attributes: queueexec and exec. The following describes the functions of these methods and attributes.

Script ()The script () in the public API actually generates an engine object and then calls the sctipt () method in the engine. This method is based onQueueexecValue, calledLoadscript ()Method to load or pre-load the incoming JS address.

Wait ()The wait () in the public API actually generates an engine object and then calls the wait () method in the engine.

Loadscript ()Load JS methods. Based on the actual browser situation and whether it is in the same domain, this method will call one of the three methods mentioned above to load JS or pre-load JS, or load the pre-loaded JavaScript code to the page.

Waitfunc ()Each engine hasReadyThe default value is false. If all JS files to be loaded by this engine have been loadedReadyTrue.Waitfunc (), ThisWaitfunc ()It generally contains the function that you want to execute after the specified JS load is complete. The next step is to trigger the next engine (if any ).

QueueexecThis is a Boolean attribute used to indicate whether the current engine needs to be preloaded when loading Js. By default,QueueexecIf this parameter is set to false, the specified JS is loaded directly.Wait ()After the method,QueueexecThe value in the new engine is true, indicating that JS in the engine is preloaded first.

ExecThis is an array where all elements are functions to be executed. When pre-loading JS,Loadscript ()Will be executed immediately to pre-load the specified JS, and the sameLoadscript ()Will be pushed to the currentEngineObjectExecArray, and in the currentEngineOfWaitfunc ()Called in sequence during execution,Loadscript ()This execution will actually load the pre-loaded js to the page.

The entire process is roughly as follows:

The above flowchart is only a simplified version (for example, the browser determines and the method to download JS is omitted). The complete logic inside labjs is more complicated.

In the figureReadyIndicates whether all JS introduced in the current engine has been loaded (labjs has an internal variable with the same name ). As you can see, labjs generatesEngineObject. All script () methods called by the chain after this actually call thisEngineThe internal script () method until. Wait () appears on the chain. The wait () method will generate a newEngineAnd then all the JS introduced through the script () method will be preloaded first, wait for the previousEngineThe load is triggered only when the load is complete.

The implementation principles of labjs are introduced here. This post has been written for a long time, and has been repeatedly modified in the computer and in the mind many times. I have always thought it was not clear enough to put it up. However, it seems that the current version is still very complicated, techniques to be writtenArticleIt's really not easy, huh, huh.

Labjs uses many techniques, such as setTimeout (FN,0. If you are interested, take some time to read it.Source code. Compared with other dynamic loading of external JS solutions, labjs is the smallest and most powerful one I have ever seen. Its biggest feature is its ability to download the JS to be loaded in parallel as much as possible, however, the execution sequence of JS can be ensured when necessary. There are many other JS loaders, but by default, they either do not support parallel downloads, or although they support parallel downloads, the execution sequence of JS cannot be guaranteed in Some browsers. From this perspective, labjs is the best of them. However, other solutions also have their own characteristics, such as requirejs. Compared with labjs, it not only loads external JS, but also dynamically defines and adds JS modules. In some application scenarios, it may be more suitable or powerful.

In addition, labjs also has some shortcomings. For example, some trick methods rely too much on the non-standard (or not defined in the Standard) features of specific browser versions, however, these features cannot be detected through Js. We can only assume that the browser version information and previous experience have or do not have certain features. This method is ugly and insecure. If a new version of a browser changes the relevant features one day, the JS Code will be completely unknown, therefore, the related functions or trick will become invalid. The best way is to directly check the browser features to complete the relevant judgment, but who makes some features really difficult to obtain? In addition, a better way is probably to promote more reasonable standards together, so that JS loader can be easily and naturally implemented in a new browser one day in the future, let labjs and other solutions completely exit the historical stage of front-end development. Perhaps this is the best future for front-end engineers.

 

Source: http://oldj.net/article/labjs-study/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.