Home > Web Front-end > JS Tutorial > Non-blocking loading performance optimization solution in JavaScript_javascript skills

Non-blocking loading performance optimization solution in JavaScript_javascript skills

WBOY
Release: 2016-05-16 16:34:37
Original
1307 people have browsed it

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

Among Yahoo’s Yslow 23 rules, one of them is to put JS at the bottom. The reason is that, in fact, most browsers use a single process to handle multiple tasks such as UI and updating Javascript, and only one task can be executed at a time. How long the Javascript is running, then how long it waits before the browser becomes idle to respond to user interaction.

At a basic level, this means that the presence of the <script> tag causes the entire page to wait for the script to be parsed and run. Regardless of whether the actual JavaScript code is inline or contained in an unrelated external file, the page download and parsing process must stop and wait for the script to complete this processing before continuing. This is an essential part of the page lifecycle, since the script may modify the page content while running. A typical example is the document.write() function, for example: <br> </p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="5199" class="copybut" id="copybut5199" onclick="doCopy('code5199')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code5199"> <br> <html><br> <head><br> <title>Script Example</title><br> </head> <br> <br> <body><br> <p><br>             <script type="text/javascript"><br>                  document.write("The date is " (new Date()).toDateString());<br>                                                                                                 </p><br> </body> <br> </html><br> <br> </div> When the browser encounters a <script> tag, as in the HTML page above, there is no way to predict whether JavaScript will add content in the <p> tag. Therefore, the browser stops, runs this JavaScript code, and then continues parsing and translating the page. The same thing happens when loading JavaScript using the src attribute. The browser must first download the code for the external file, which takes some time, and then parse and run the code. During this process, page parsing and user interaction are completely blocked. <br> Because scripts block the download process of other page resources, the recommended approach is to place all <script> tags as close to the bottom of the <body> tag as possible to minimize the impact on the download of the entire page. For example: <p> <br></p> <div class="codetitle"><span><a style="CURSOR: pointer" data="96913" class="copybut" id="copybut96913" onclick="doCopy('code96913')">Copy code<u></u></a> The code is as follows:</span></div> <div class="codebody" id="code96913"> <html><br> <head><br> <title>Script Example</title><br> <link rel="stylesheet" type="text/css" href="styles.css"> <br> </head><br> <br> <body><br> <p>Hello world!</p><br> <-- Example of recommended script positioning --> <br>            <script type="text/javascript" src="file1.js"></script>
          
         



This code shows the recommended location of the <script> tag in the HTML file. Although the script downloads block each other, the page has been downloaded and displayed in front of the user, and the speed of entering the page will not appear too slow. This is what was mentioned above about putting JS at the bottom. <p> </p>In addition, Yahoo! creates a "union handle" for its "Yahoo! User Interface (YUI)" library, which is implemented through their "Content Delivery Network (CDN)" of. Any website can use a "union handle" URL to indicate which files in the YUI package are included. For example, the following URL contains two files: <p> <br></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="74887" class="copybut" id="copybut74887" onclick="doCopy('code74887')">Copy code<u></u></a> The code is as follows:</span><div class="codebody" id="code74887"> <br> <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, the two files will be merged together and returned to the client. In this way, there is no need for two <script> tags (each loading a file), and one <script> tag can load them. This is the best way to include multiple external Javascripts in an HTML page. </p> <p><strong>Noblocking Scripts Non-blocking Scripts</strong></p> <p>The above is the best way to load multiple Javascript scripts in the initial state of the page. Javascript tends to block certain browser processes, such as http requests and interface refreshes, which is the most significant performance problem faced by developers. Keeping JavaScript files short and limiting the number of http requests are just the first steps in creating responsive web applications. </p> <p>But such as large web pages with a lot of JS code, keeping the source code short is not always the best choice. So, non-blocking scripts came into being. What we need is to gradually add javascript to the page without blocking the browser to some extent. </p> <p>The key to not blocking the script is to wait for the page to finish loading before loading the Javascript source code, which means starting to download the code after the window's load event is issued. </p> <p>Related explanation: </p> <p>The load event of window will only be triggered once and only once after the page is loaded. <br> window.onload=function(){} must wait until all the content in the web page is loaded (including all associated files of the element, such as images) before it can be executed. That is, Javascript can only access any element in the page at this time. </p> <p>Several methods are as follows: </p> <p><strong>Deferred Scripts Deferred Scripts</strong></p> <p>Html4 defines an extended attribute for the <script> tag: defer. </p> <p>This defer attribute indicates that the script contained in the element is not intended to modify the DOM, so the code can be executed later. The defer attribute is only supported by Internet Explorer 4 and Firefox 3.5, making it not an ideal cross-browser solution. On other browsers, the defer attribute will be ignored. Therefore, the <script> tag will be processed in the normal default manner, which will cause blocking. If supported by all major browsers, this is still an effective solution. <br> </p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="14408" class="copybut" id="copybut14408" onclick="doCopy('code14408')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code14408"> <br> <script type="text/javascript" src="file1.js" defer></script>

A <script> tag with a defer attribute can be placed anywhere in the document and will initiate downloading as it is parsed until the DOM is loaded (before the onload event handler is called). When a defer Javascript file is downloaded, it does not block other processing by the browser, so the files can be downloaded in parallel with other resources. </p> <p>You can use the following code to test whether the browser supports the defer attribute: <br> </p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="95845" class="copybut" id="copybut95845" onclick="doCopy('code95845')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code95845"> <br> <html><br> <head><br> <title>Script Defer Example</title><br> </head> <br> <br> <body><br> <script defer> alert("defer");</script>
<script> alert("script"); </script>
<script> window.onload = function(){ alert("load");}; </script>


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 order of the pop-up dialog boxes is "script", "load", "defer".

Dynamic Script Elements Dynamic Script Elements

DOM allows us to use Javascript to dynamically create almost all document content in HTML. A new <script> element can be created very easily through the standard DOM: </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="78091" class="copybut" id="copybut78091" onclick="doCopy('code78091')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code78091"> <br> 1 var script = document.createElement ("script");<br> 2 script.type = "text/javascript";<br> 3 script.src = "file1.js"; <br> 4 document.body.appendChild(script);<br> </div> <p>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 key point of this technology is that no matter where the download is initiated, the file downloads and runs without blocking other page processing. </p> <p>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 execution). </p> <p>In most cases, we hope to call a function to dynamically download Javascript files. The following function package implements the standard implementation and IE implementation: </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="4795" class="copybut" id="copybut4795" onclick="doCopy('code4795')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code4795"> <br> function loadScript(url, callback){<br> var script = document.createElement ("script") ;<br> ​ script.type = "text/javascript";<br>        <br> If (script.readyState){ //IE<br>            script.onreadystatechange = function(){<br> If (script.readyState == "loaded" || script.readyState == "complete"){<br>               script.onreadystatechange = null;<br>               callback(); <br>            }<br>         };<br>         } <br>         else { //Others<br>           script.onload = function(){ callback();<br> }; <br> }<br> Script.src = url;<br> Document.getElementsByTagName("head")[0].appendChild(script); <br> }<br> <br> loadScript("file1.js", function(){ //Call <br> alert("File is loaded!"); <br> });<br> </div> <p>This function accepts two parameters: the URL of the Javascript file and a callback function that is triggered when the Javascript reception is completed. Property inspection is used to decide which events to monitor. The final step is the src attribute and adding the javascript file to the head. </p> <p>Dynamic script loading is the most commonly used mode in non-blocking Javascript downloads because it works across browsers and is simple and easy to use. </p> <p><strong>XMLHttpRequest Script Injection XHR script injection</strong></p> <p>Another way to get scripts in a non-blocking way is to use an XMLHttpRequest (XHR) object to inject the script into the page. This technique first creates an XHR object, then downloads the Javascript file, and then uses a dynamic <script> element to inject the Javascript code into the page. Watch the demo: </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="24685" class="copybut" id="copybut24685" onclick="doCopy('code24685')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code24685"> <br> var xhr = new XMLHttpRequest(); <br> xhr.open("get", "file1.js", true); <br> xhr.onreadystatechange = function(){<br> If (xhr.readyState == 4){<br> If (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){ // Check http status code <br>         var script = document.createElement("script"); <br>           script.type = "text/javascript";<br>            script.text = xhr.responseText;<br>              document.body.appendChild(script);<br>          } <br> }<br> }; <br> xhr.send(null);<br> </div> <p>This code sends a file get request to the server to obtain file1.js. The onreadystatechange event handler checks whether readyState is 4, and then checks whether the http status code is valid (200 indicates that the client request has been successful, 2xx indicates a valid response, and 304 indicates a cached response). If a valid response is received, a new <script> element is created and its text attribute is set to the responseText string received from the server. Doing this will actually create a <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. </p> <p>The advantage of this method is that it has good compatibility and you can download Javascript code that is not executed immediately. Since the code is returned outside the <script> tag, it will not automatically execute after downloading, allowing you to defer execution. </p> <p>The determination of this method is subject to the same origin restriction of the browser. The Javascript file must be placed in the same domain as the page and cannot be downloaded from the CDN (Content Delivery Network). For this reason, large web pages generally do not use XHR script injection technology. </p> <p><strong>Recommended Noblocking Pattern Recommended non-blocking pattern</strong></p> <p>The recommended method of loading large amounts of Javascript into a page is a two-step process: </p> <p>The first step includes the code required to dynamically load Javascript, and then loads the parts other than Javascript required for page initialization. This part of the code should be as small as possible and may only contain the loadScript() function. It downloads and runs very quickly and will not cause much interference to the page. </p> <p>The second step, when the initial code is ready, use it to load the rest of the Javascript. </p> <p>For example: <br> </p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="91573" class="copybut" id="copybut91573" onclick="doCopy('code91573')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code91573"> <br> 1 <script type="text/javascript" src="loader.js"><br> 2 </script>


Place this code before the closing tag of body . The advantage of doing this is that, first of all, it ensures that running Javascript will not affect the display of other parts of other pages. Secondly, when the second part of the Javascript file is downloaded, all the DOM necessary for the application has been created and is ready to be accessed, avoiding the use of additional event processing (such as window.onload) to know whether the page is ready. .

Another option is to embed the loadScript() function directly into the page, which can reduce the overhead of an http request. For example:

Copy code The code is as follows:

1

Once the page initialization code is downloaded, you can also use the loadScript() function to load additional functions required by the page.

Introducing a common tool, Ryan Grove of Yahoo! Search created the LazyLoad library (see: http://github.com/rgrove/lazyload/ ). LazyLoad is a powerful loadScript() function. LazyLoad is only about 1.5KB after minification. Usage examples are as follows:

Copy code The code is as follows:



Summary

1. Place all

Latest Articles by Author
Latest Issues
Related Topics
More>
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template