Non-blocking loading strategy for high performance javascript--scripts

Source: Internet
Author: User

JavaScript's performance in the browser can be said to be the most important usability issue that front-end developers face.

In Yahoo's Yslow23 rule, one of them is to put JS on the bottom of the line. The reason is that, in fact, most browsers use a single process to process the UI and update JavaScript to run multiple tasks, while only one task can be executed at a time. How long JavaScript has been running, and how long it will wait before the browser is idle to respond to user interaction.

From the basic level, this means that the appearance of the <script> tag makes the entire page wait for the script to parse and run. Regardless of whether the actual JavaScript code is inline or contained in an extraneous external file, the page download and parsing process must stop and wait for the script to complete the processing before continuing. This is an essential part of the page life cycle, because the script may modify the page content while it is running. A typical example is the document.write () function, for example:

1 

When the browser encounters a <script> tag, as in the HTML page above, it is impossible to predict whether or not JavaScript will add content to the <p> tag. Therefore, 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 resolves 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, it is recommended that all <script> tags be placed as close to the bottom of the <body> tag as possible, minimizing the impact on the entire page download. For example:

1 

This code shows the location of the recommended <script> tags in the HTML file. Although script downloads are blocked from one another, the page is downloaded and displayed in front of the user, and the speed of the page does not appear too slow. This is the above mentioned to put JS to the bottom .

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

1 <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 the 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 combined and returned to the client. In this way, it is no longer necessary to have two <script> tags (one file per tag), and a <script> tag to load them. This is the best way to include multiple external JavaScript on an HTML page.

Noblocking Scripts non-blocking scripts

The above is the best way to load the initial state of the page with multiple JavaScript scripts. JavaScript tends to block some of the browser's processing processes, such as HTTP requests and interface refreshes, which are the most noticeable 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 the best choice. So, the non-blocking script came into being, and what we needed was to step into the page to add JavaScript, in a way that would not block the browser.

The key to non-blocking scripting is that when the page finishes loading, the JavaScript source is loaded, which means that the code is downloaded after the window's Load event has been issued.

Related explanations:

The Load event for window only fires once and only once when the page is loaded.

Window.onload=function () {} must wait until all content in the Web page is loaded (including all associated files for the element ) to execute, that is, JavaScript can now access any element in the page.

Several methods are as follows:

Deferred Scripts Deferred Script

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

This defer property indicates that the script contained in the element is not intended 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 as normal by default, which will cause blocking. This is still an effective solution if supported by various mainstream browsers.

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

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

You can use the following code to test whether the browser supports the Defer property:

1 

If the browser does not support defer, then the order of the popup dialogs is "defer", "script", "load".

If the browser supports defer, then the order of the popup dialogs is "script", "Load", "defer".

Dynamic SCRIPT Element Elements

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

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 as soon as the element is added to the page. The point of this technique is that no matter where the download is initiated, the download and operation of the file does not block other page processing processes.

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

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 implementations:

1  function Loadscript (URL, callback) {2     var script = document.createelement ("script"); 3  script.type = "Te Xt/javascript "; 4       5     if (script.readystate) {//ie 6        script.onreadystatechange = function () {7          if (script.readystate = = " Loaded "| | Script.readystate = = "complete") {8            script.onreadystatechange = NULL; 9            callback ();           }11        };12      } The      else {//others14        script.onload = function () {callback (); n      };    }17    script.src = url;18    document.getelementsbytagname ("Head") [0].appendchild (script)  ,}20 loadscript ("File1.js", function () {  //call on     alert ("File is loaded!"); 23});

This function accepts two parameters: the URL of the JavaScript file and a callback function that fires when the JavaScript receive is complete. The property check is used to determine which event to monitor. The last step of the SRC attribute and add the JavaScript file to the head.

Dynamic scripting loads the most common pattern in non-blocking JavaScript downloads, because it can be cross-browser and easy to use.

XMLHttpRequest Script injection XHR scripts injection

Another way to get a script in a non-blocking way is to use the XMLHttpRequest (XHR) object to inject the script into the page. 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:

1 var xhr = new XMLHttpRequest ();  2 Xhr.open ("Get", "File1.js", true);  3 Xhr.onreadystatechange = function () {4     if (xhr.readystate = = 4) {5       if (xhr.status >= && Xhr.statu S < 300 | | Xhr.status = = 304) {//Check HTTP status Code 6         var script = document.createelement ("script");  7         script.type = "Text/javascript"; 8         script.text = xhr.responsetext; 9         document.body.appendChild (script ); ten       }    }12}; Xhr.send (NULL);

This code sends a GET request for a file1.js file to the server. 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 was successful, 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 will actually create an <script> element with inline code, and once the new <script> element is added to the document, the code will be 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. Since the code is returned outside of the <script> tag, it is not automatically executed after it is downloaded, which allows you to defer execution.

This method is determined to be subject to browser-like limitations, and JavaScript files must be placed in the same domain as the page and cannot be downloaded from the CDN (content distribution Network contents Delivery networks). For this reason, large web pages typically do not use XHR script injection technology.

Recommended noblocking pattern recommended non-blocking mode

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

    • The first step is to include the code required to dynamically load the JavaScript, and then load the page initialization required in addition to the JavaScript section. This part of the code is as small as possible and may contain only the Loadscript () function, which is very fast to download and run, and will not cause much disruption to the page.
    • In the second step, when the initial code is ready, use it to load the rest of the JavaScript.

For example:

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 label </body>. The advantage of this is that, first, this ensures that JavaScript runs without affecting other parts of the page display. Second, when the second part of the JavaScript file is downloaded, the DOM required by all the applications is 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 reduces the overhead of an HTTP request. For example:

1 <script type= "Text/javascript" >  2   function loadscript (URL, callback) {3     var script = Document.createelement ("script"); 4  script.type = "Text/javascript"; 5     6     if (script.readystate) {//ie script.onreadystatechange = function () {7       if (script.readystate = = "Loaded" | | script.readystate = = "complete") {8         Script.onreadystatechange = Null;
   9         Callback (), ten       }     };12   } else {//others    script.onload = function () {    callback ( );    };16   }17   script.src = URL,   document.getelementsbytagname ("Head") [0].appendchild (script) ;}20 loadscript ("The-rest.js", function () {application.init ();); </script>

Once the page initialization code download is complete, you can also use the Loadscript () function to load the additional function functions required for the page.

Introducing a common 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 finishing. Examples of usage are as follows:

1 <script type= "Text/javascript" src= "Lazyload-min.js" ></script> 2 <script type= "Text/javascript" > 3 Lazyload.js ("The-rest.js", Function () {4 application.init (); 5}); 6 </script>

  

Summary Summary

    • Place all <script> tags at the bottom of the page, immediately above the tab </body> close. This method ensures that the page finishes parsing before the script runs.
    • Package the script as a group. With fewer <script> labels on the page, the page loads faster and responds more quickly. This is true regardless of the external script file or inline code.
    • There are several ways to download JavaScript using non-blocking methods:
      • Add defer property for <script> tags
      • Dynamically create <script> elements, use it to download and execute code
      • Download the code with the XHR object and inject it into the page

The above strategy can greatly improve the actual performance of users who use JavaScript code.

Refer to the book "High Performance JavaScript".

Http://www.cnblogs.com/coco1s/p/4010310.html

Non-blocking loading strategy for high performance javascript--scripts

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.