_javascript techniques for the optimal scheme of non-blocking loading performance in JavaScript

Source: Internet
Author: User

The performance of JavaScript in the browser can be said to be the most important usability problem faced by the front-end developers.

One of the Yslow23 rules for Yahoo is to put JS on the bottom. The reason is that, in fact, most browsers use a single process to process the UI and update the JavaScript run, and so on, and only one task can be executed at the same time. How long JavaScript has been running, and how long it will wait before the browser is idle to respond to user interaction.

On the basic level, this means that the presence of <script> tags causes the entire page to wait for the script to parse and run. Whether the actual JavaScript code is inline or contained in an unrelated external file, the page download and parsing process must stop, waiting for the script to complete the processing before continuing. This is an essential part of the page lifecycle because the script may modify the content of the page while it is running. A typical example is the document.write () function, for example:

Copy Code code as follows:

<title>script example</title>

<body>
<p>
<script type= "Text/javascript" >
document.write ("The date is" + (new Date ()). toDateString ());
</script>
</p>
</body>

When a browser encounters a <script> tag, as in the HTML page above, it is not possible to predict whether JavaScript adds content to the <p> tag. So, the browser stops, runs this JavaScript code, and then continues parsing and translating the page. The same thing happens in the process of loading JavaScript using the SRC attribute. The browser must first download the code for the external file, which takes some time, and then parses and runs the code. In this process, page parsing and user interaction are completely blocked.

Because the script blocks the download process for other page resources, the recommended approach is to place all <script> tabs as close to the bottom of the <body> label as possible, minimizing the impact on the entire page download. For example:

Copy Code code as follows:

<title>script example</title>
<link rel= "stylesheet" type= "Text/css" href= "Styles.css" >

<body>
<p>hello world!</p>
<--Example of recommended script positioning-->
<script type= "Text/javascript" src= "File1.js" ></script>
<script type= "Text/javascript" src= "File2.js" ></script>
<script type= "Text/javascript" src= "File3.js" ></script>
</body>

This code shows the location of the recommended <script> tags in the HTML file. Although the script downloads are blocking each other, the page has been downloaded and displayed in front of the user, and the page does not appear to be too slow. This is the above mentioned to put JS to the bottom.

In addition, Yahoo! creates a "union handle" for his "Yahoo! User interface (Yahoo! User Interface,yui)" library, which is implemented through their content delivery network (contents Delivery NETWORK,CDN). Any web site can use a "union handle" URL to indicate which files are included in the YUI package. For example, the following URL contains two files:

Copy Code code as follows:

<script type= "Text/javascript" src= "http://yui.yahooapis.com/combo?2.7.0/build/yahoo/yahoo-min.js&2.7.0/ Build/event/event-min.js "></script>

This URL calls the 2.7.0 version of Yahoo-min.js and event-min.js files. These files are two separate files on the server, but when the server receives this URL request, two files are merged and returned to the client. In this way, you no longer need two <script> tags (each tag to load a file), a <script> tag can load them. This is the best way to include multiple external JavaScript in an HTML page.

Noblocking Scripts non-blocking script

The above is the best way for page initial state to contain multiple JavaScript script loads. JavaScript tends to block browser processing, such as HTTP requests and interface refreshes, which are the most significant performance issues facing developers. Keeping JavaScript files short and limiting the number of HTTP requests is just the first step in creating a responsive Web application.

However, such as large web pages have a large number of JS code, keep the source short is not always a best choice. So, non-blocking scripts come into being, and what we need is to add JavaScript incrementally to the page and not block the browser to some extent.

The key to not blocking the script is to load the JavaScript source after the page finishes loading, which means downloading the code after the window's Load event has been issued.

Related explanations:

The window's Load event will only be triggered once and only once after the page has finished loading.
Window.onload=function () {} must wait for all content in the Web page to be loaded (including all associated files of the element, such as pictures) to execute, that is, JavaScript can access any element on the page at this time.

The following methods are as follows:

Deferred Scripts Deferred Script

HTML4 defines an extended attribute for the <script> tag: defer.

This defer property indicates that the script contained in the element does not intend to modify the DOM, so the code can be executed later. The Defer property is supported only by Internet Explorer 4+ and Firefox 3.5+, and it is not an ideal cross-browser solution. On other browsers, the defer property is ignored. So the,<script> tag will be handled in the normal default manner, which can cause blocking. This is still an effective solution if you have the support of all the major browsers.

Copy Code code as follows:

<script type= "Text/javascript" src= "File1.js" defer></script>

A <script> tag with the defer attribute can be placed anywhere in the document, and it will start the download when it is resolved until the DOM load completes (before the OnLoad event handle is invoked). When a defer JavaScript file is downloaded, it does not block other browser processing, so these files can be downloaded in parallel with other resources.

You can use the following code to test whether the browser supports defer properties:

Copy Code code as follows:

<title>script Defer example</title>

<body>
<script defer> alert ("Defer");</script>
<script> alert ("script"); </script>
<script> window.onload = function () {alert ("Load");}; </script>
</body>

If the browser does not support defer, the Order of the pop-up dialog boxes is "defer", "script", "load".

If the browser supports defer, the sequence of pop-up dialogs is "script", "Load", "defer".

Dynamic script Elements dynamically scripting elements

Dom allows us to dynamically create almost all of the document content of HTML using JavaScript, and a new <script> element can be created very easily through the standard DOM:

Copy Code code as follows:

1 var script = document.createelement ("script");
2 Script.type = "Text/javascript";
3 script.src = "File1.js";
4 document.body.appendChild (script);

The new <script> element loads the file1.js source file. This file starts downloading immediately after the element has been added to the page. The point of this technique is that no matter where you start the download, the download and run of the file will not block other page processing.

When a file is downloaded using a dynamic script node, the returned code is usually executed immediately (except for Firefox and Opera, which waits for all previous dynamic script nodes to finish executing).

In most cases, we want to invoke a function to implement a dynamic download of JavaScript files. The following function encapsulation implements the standard implementation and IE implementation:

Copy Code code as follows:

function Loadscript (URL, callback) {
var script = document.createelement ("script");
Script.type = "Text/javascript";

if (script.readystate) {//ie
Script.onreadystatechange = function () {
if (script.readystate = = "Loaded" | | | script.readystate = = "complete") {
Script.onreadystatechange = null;
Callback ();
}
};
}
else {//others
Script.onload = function () {callback ();
};
}
script.src = URL;
document.getElementsByTagName ("Head") [0].appendchild (script);
}

Loadscript ("File1.js", function () {//Call
Alert ("File is loaded!");
});

This function accepts two parameters: the URL of a JavaScript file and a callback function that fires when JavaScript receives completion. Property checks are used to determine which event to monitor. The last step of the SRC attribute and add the JavaScript file to the head.

Dynamic script loading is the most common pattern in non-blocking JavaScript downloads because it can be used across browsers and is easy to use.

XMLHttpRequest Script injection XHR scripts injection

Another way to get a script in non-blocking mode is to inject the script into the page using the XMLHttpRequest (XHR) object. This technique first creates a Xhr object, then downloads the JavaScript file, and then injects the JavaScript code into the page with a dynamic <script> element. See Demo:

Copy Code code as follows:

var xhr = new XMLHttpRequest ();
Xhr.open ("Get", "File1.js", true);
Xhr.onreadystatechange = function () {
if (xhr.readystate = = 4) {
if (xhr.status >= && xhr.status < $ | | xhr.status = 304) {//Check HTTP status code
var script = document.createelement ("script");
Script.type = "Text/javascript";
Script.text = Xhr.responsetext;
Document.body.appendChild (script);
}
}
};
Xhr.send (NULL);

This code sends a file GET request to the server that gets file1.js. The onReadyStateChange event handler checks that the readystate is not 4, and then checks that the HTTP status code is not valid (200 indicates that the client request has succeeded, 2xx represents a valid response, and 304 represents a cached response). If you receive a valid response, create a new <script> element and set its Text property to the ResponseText string received from the server. Doing so actually creates a <script> element with inline code, and once the new <script> element is added to the document, the code is executed and ready to be used.

The advantage of this approach is that compatibility is good, and you can download JavaScript code that is not executed immediately. Because the code returns outside the <script> tag, it does not automatically execute after downloading, which allows you to postpone execution.

This method is determined to be subject to browser-origin restrictions, JavaScript files must be placed in the same domain as the page, and cannot be downloaded from the CDN (Content distribution Network Delivery network). For this reason, large Web pages usually do not use the XHR scripting injection technique.

Recommended noblocking pattern recommended in the non-blocking mode

The recommended way to load a lot of JavaScript into a page is two steps:

The first step is to include the code needed to dynamically load JavaScript, and then load the parts of the page that are required for initialization except JavaScript. This part of the code as small as possible, may contain only the Loadscript () function, it's download and run very quickly, does not cause a lot of interference on the page.

The second step, when the initial code is ready, uses it to load the rest of the JavaScript.

For example:

Copy Code code as follows:

1 <script type= "Text/javascript" src= "Loader.js" >
2 </script> <script type= "Text/javascript" >
3 Loadscript ("The-rest.js", function () {
4 Application.init ();
5});
6
7 </script>

Place this code before the body's close tag </body>. The good thing about this is that, first of all, this ensures that JavaScript runs will not affect other parts of the other page display. Second, when the second part of the JavaScript file is downloaded, all applications must have the DOM created and ready to be accessed, avoiding the use of additional event handling (such as window.onload) to know if the page is ready.

Another option is to embed the Loadscript () function directly in the page, which can reduce the overhead of an HTTP request. For example:

Copy Code code as follows:

1 <script type= "Text/javascript" >
function Loadscript (URL, callback) {
var script = document.createelement ("script");
Script.type = "Text/javascript";

if (script.readystate) {//ie script.onreadystatechange = function () {
if (script.readystate = = "Loaded" | | | script.readystate = = "complete") {
Script.onreadystatechange = null;
Callback ();
}
};
else {//others
Script.onload = function () {
Callback ();
};
}
script.src = URL;
document.getElementsByTagName ("Head") [0].appendchild (script);
}

Loadscript ("The-rest.js", function () {
Application.init ();
});
</script>

Once the page initialization code has been downloaded, you can also use the Loadscript () function to load the additional functional functions required by the page.

Introducing a generic tool, Yahoo! Search's Ryan Grove created the Lazyload library (see: http://github.com/rgrove/lazyload/). Lazyload is a powerful loadscript () function. The lazyload is only about 1.5KB after fine contraction. Examples of usage are as follows:

Copy Code code as follows:

<script type= "Text/javascript" src= "Lazyload-min.js" ></script>
<script type= "Text/javascript" >
Lazyload.js ("The-rest.js", function () {
Application.init ();
});
</script>

Summary Summary

1. Place all <script> labels at the bottom of the page, immediately above the close tag </body>. This method ensures that the page finishes parsing before the script runs.

2. Pack the scripts into groups. The less the page's <script> label, the faster the page loads and the quicker the response. This is true regardless of external script files or inline code.

3. There are several ways to download JavaScript using non-blocking mode:

1. Add defer property to <script> tag
2. Dynamically create <script> elements, use it to download and execute code
3. Download the code with the XHR object and inject it into the page

With these strategies, you can dramatically improve the actual performance of users who use JavaScript code.

Reference book "High Performance JavaScript".

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.