JavaScript asynchronous loading analysis of _javascript techniques

Source: Internet
Author: User
Tags script tag

Objective

I'm sure you've met a lot of questions about JavaScript script loading. Mainly in a few points--

File loading, file dependencies, and execution order problems with 1> synchronization scripts and asynchronous scripts
Performance optimization problems with 2> synchronization scripts and asynchronous scripts


In-depth understanding of all aspects of the script loading, not only to solve the practical problems, more conducive to the performance optimization of the GRASP and implementation.

Let's look at a random script tag code--


Copy Code code as follows:

<script src= "Js/myapp.js" ></script>


If placed on

Copy Code code as follows:

<! DOCTYPE html>
<meta charset= "UTF-8" >
<title> Asynchronous Load Script</title>
<script src= "Js/test.js" ></script>
<body>
<div> I am content </div>

</body>

Among them, the content of Test.js--


Copy Code code as follows:

Alert (' I am head inside of the script code, the implementation of JS here, before starting to do the body content rendering! ');


As we'll see, alert is a pause point, at which point the page is blank. Note, however, that the entire page has already been loaded, and if the body contains some of the SRC attribute tags (such as the IMG tag above), the browser has started loading the relevant content. In short, note that the--JS engine and the rendering engine are mutually exclusive (some books call it the UI thread).

So we need--the scripts that are responsible for making the page look better and more used should be loaded immediately, and the scripts that can be loaded later are loaded.

One, script delay execution

It's getting more and more popular. Put the script on the end of the page <body> tag. This allows the user to see the page more quickly on the one hand, while the script can directly manipulate the DOM elements that have already been loaded. For most scripts, this "move" is a huge improvement. The page model is as follows--


Copy Code code as follows:

<! DOCTYPE html>
<!--metadata and Scriptsheets go here-->
<script src= "Headscript.js" ></script>
<body>
<!--content goes here-->
<script src= "Bodyscript.js" ></script>
</body>

This really speeds up the rendering time of the page, but note that this may give the user an opportunity to interact with the page before loading bodyscript. Because browsers cannot load these scripts until the entire document is loaded, this can be a major bottleneck for large documents that are delivered over a slow connection.

Ideally, the script should load concurrently with the loading of the document and not affect the rendering of the DOM. This allows the script to run once the document is ready because the script has been loaded in the order of <script> tags.

We can use defer to fulfill this demand, namely--


Copy Code code as follows:

<script src= "Deferredscript.js" ></script>


Adding the Defer property is equivalent to telling the browser: Please start loading the script right away, but wait until the document is ready and all previous scripts with the defer attribute are finished before running it.

In this way, a delay script is placed in the head tag, which brings all the benefits of the script to the body tag and increases the loading speed of large documents. The page pattern at this point is--


Copy Code code as follows:

<! DOCTYPE html>
<!--metadata and Scriptsheets go here-->
<script src= "Headscript.js" ></script>
<script src= "Deferredscript.js" defer></script>
<body>
<!--content goes here-->
</body>

But not all browsers support defer (for some modern browsers, if you declare defer, their internal scripts will not perform document.write and DOM rendering operations.) Ie4+ supports defer properties). This means that if you want to make sure that your delay scripts run after the document is loaded, you must encapsulate all the deferred script code in a structure such as jquery $ (document). Ready. This is worthwhile because almost 97% of visitors enjoy the benefits of parallel loading, while another 3% of visitors can still use fully functional JavaScript.

Second, the full parallelism of the script

Let the script load and execute one step at a time, I don't want to wait until the defer script runs one after another (defer lets us think of an orderly queue scenario that silently waits for the document to load), not to run the scripts until the document is ready, I want to load and run the scripts as soon as possible. The async attribute of HTML5 is also thought of here, but note that it is a chaotic state of anarchy.

For example, we load two completely unrelated third-party scripts, and the pages run well without them, and don't care who runs them first. Therefore, using the Async attribute for these third-party scripts, the equivalent of a penny without a flower increases their speed.

The Async property is HTML5 added. function is similar to defer, which allows DOM rendering at the same time as downloading scripts. However, it will be executed as soon as possible after downloading (that is, the JS engine is idle and executed immediately), and the script will not be guaranteed to execute sequentially. They will be completed before the OnLoad event.

Firefox 3.6, Opera 10.5, IE 9, and the latest chrome and Safari all support the async attribute. You can use both async and defer, so all ie after IE 4 supports asynchronous loading, but be aware that async overrides defer.

Now the page model is as follows--

Copy Code code as follows:

<! DOCTYPE html>
<!--metadata and Scriptsheets go here-->
<script src= "Headscript.js" ></script>
<script src= "Deferredscript.js" defer></script>
<body>
<!--content goes here-->
<script src= "asyncscript1.js" Async defer></script>
<script src= "asyncscript2.js" Async defer></script>
</body>

Note The order of execution here-the individual script files are loaded, followed by the Headscript.js, followed by the DOM rendering in the background loading the defferedscript.js. The Defferedscript.js and the two asynchronous scripts are then run at the end of the DOM rendering, and note that the two scripts will run in a disorderly operation for browsers that support async properties.

Third, programmable script loading

Although the above two script properties are very appealing, they are not widely used because of compatibility issues. So we use more scripts to load other scripts. For example, we just want to load a script for a user who satisfies a certain condition, which is often referred to as lazy load.

At the browser API level, there are two reasonable ways to crawl and run server scripts--

1> generates AJAX requests and processes responses with the Eval function

2> inserts <script> tags into the DOM

The latter approach is better, because browsers worry about generating HTTP requests for us. Furthermore, Eval has some practical problems: leaking scopes, debugging a mess, and potentially reducing performance. So, to load a script named Feture.js, we should use code similar to the following:


Copy Code code as follows:

var head = document.getElementsByTagName (' head ') [0];
var script = document.createelement (' script ');
SCRIPT.SRC = ' feature.js ';
Head.appendchild (script);

Of course, we're dealing with callback sniffing, and the HTML5 specification defines an onload attribute that can bind a callback.


Copy Code code as follows:

Script.onload = function () {
Console.log (' script loaded ... ');
}


However, IE8 and older versions do not support the onload, and they support onreadystatechange. Also, there are still strange problems with error handling. Here, you can refer to some popular school-based loading library, such as LABJS, Yepnope, Requirejs and so on.

Like the following, you encapsulate a simple Loadjs file--


Copy Code code as follows:

var Loadjs = function (url,callback) {
var head = document.getElementsByTagName (' head ') [0];
var script = document.createelement (' script ');
script.src = URL;
Script.type = "Text/javascript";
Head.appendchild (script);

Script tags, ie under the onreadystatechange event, the standard for the OnLoad event
Ie9+ also supports the OnLoad standard of the Consortium
var ua = navigator.useragent,
Ua_version;
Ie6/7/8
if (/msie) ([^;] +)/.test (UA)) {
Ua_version = parsefloat (regexp["$"], 10);
if (ua_version <= 8) {
Script.onreadystatechange = function () {
if (this.readystate = = "Loaded") {
Callback ();
}
}
} else {
Script.onload = function () {
Callback ();
};
}
} else {
Script.onload = function () {
Callback ();
};
}
};

For the document.write of the way to load the script asynchronously, here is not to say, now very few people do so, because the browser is the difference between the big head.

Note that using the Image object to preload the JS file asynchronously, the JS code inside will not be executed.

Finally, talk about the asynchronous load script in Requirejs.

Requirejs does not guarantee that target scripts are run sequentially, but that they are run in order to meet their dependency requirements. This ensures that all scripts are loaded in parallel as soon as possible, and that these scripts are executed in a methodical manner according to the dependency topology.

Iv. Summary

OK, speaking of which, the statement of the asynchronous load script is over. Again, I'm just babbling about the optimization sequence here--

1> Traditional way, we embed the script tag directly into the HTML document, which is divided into two situations

A> embedded in the head tag-note that this does not affect the parallel loading of other static resource files in the document's content, which affects the rendering of the content of the document, where Dom rendering is blocked and rendered screen.

B> embedded into the bottom of the body tag-to avoid the screen phenomenon, we give priority to the DOM rendering, then execute the script, but the problem comes. Let's start with the first question--if the DOM document has a larger content, the interaction event binding has a delay and the experience is a little bit worse. Of course, we need to make sure that important scripts are prioritized, depending on the requirements. Second question--because the script file as it is to the bottom of the body, the loading of these scripts is delayed relative to the script in the head. So, as for the bottom of the body, it is not the end of optimization.

C> Add the Defer attribute--We want the script to load in parallel as early as possible, and we'll still put this batch of scripts in the head. The loading of the script should be done concurrently with the loading of the document, and it does not affect the rendering of the DOM. This allows the script to run once the document is ready. So there is the defer property. But to be aware of its compatibility, for browsers that do not support defer properties, we need to encapsulate the code in a jquery $ (document). Ready. It is important to note that all the scripts for defer properties are executed sequentially in their order of appearance, so it is also strictly synchronized.

On the 2>, it's all about executing scripts synchronously (note that the loading process of these scripts is parallel, but who triggers the request after the first trigger the difference is the next optimization point is "parallel execution script", of course, we know that a point of time, only to execute a JS file, where the "parallel "Means, who first loaded, as long as the JS engine idle, immediately implemented." The optimization here is divided into two types-

a> Add Async This attribute--it does do what we call the optimization point above, but it has a very high limitation, that is simply loading on a dependent script, the most appropriate example is to introduce multiple third-party scripts. There is the combination with the Deffer attribute, it is really to let the people's brains. Of course, it also has compatibility issues. The above three problems lead to its application is not widespread. When using async, we must strictly pay attention to the dependency problem.

b> script Load Script--Obviously, we use it to achieve the goal of "parallel execution of scripts." At the same time, we are also convenient to control the problem of scripting dependencies, we use such as Requirejs for JS asynchronous loading of intelligent loading management.

Okay, here's the story.

Here, I'm just talking about the contents of the asynchronous load script. There is also a piece of content that asynchronously loads a style file or other static resource. Cond......

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.