JavaScript improves loading and execution efficiency, and javascript Execution Efficiency

Source: Internet
Author: User

JavaScript improves loading and execution efficiency, and javascript Execution Efficiency

Preface

Whether JavaScript code is embedded or in an external link file, the page download and rendering must be stopped and the script execution is complete. The longer the JavaScript Execution process takes, the longer the browser will wait to respond to user input. The reason for blocking when the browser downloads and executes the script is that the script may change the page or JavaScript namespace, which may affect the content of the subsequent page.

A typical example is to usedocument.write().

JavaScript code embedding example

When the browser encounters a <script> tag, the current html page cannot know whether JavaScript will add content to the <p> tag, introduce other elements, or even remove the tag. Therefore, the browser will stop processing the page, first execute JavaScript code, and then continue parsing and rendering the page. The same situation occurs when JavaScript is loaded using the src attribute. the browser must take the time to download the code in the external link file, parse it, and execute it. In this process, page rendering and user interaction are completely blocked.

Script location

The HTML 4 specification specifies that the <script> tag can be placed in the

Example of low-efficiency script location

However, this conventional approach hides serious performance problems. In the example in Listing 2, when the browser parses the <script> tag (Row 3), the browser stops parsing the subsequent content, and downloads the script file first, and execute the code, which means that the styles.css style file and the <body> label cannot be loaded, because the <body> label cannot be loaded, the page cannot be rendered. Therefore, the page is blank before the JavaScript code is fully executed.

Because the script will block the download of other resources on the page, we recommend that you put all the <script> labels at the bottom of the <body> label to minimize the impact on the download of the entire page.

Example of recommended code placement

This code shows the recommended location for placing the <script> tag in the HTML document. Although the script download will block another script, most of the content on the page has been downloaded and displayed to the user, so the page download will not appear too slow. This is the primary rule for optimizing JavaScript: place the script at the bottom.

Organization script

Because page rendering is blocked during initial download of each <script> tag, reducing the number of <script> tags contained in the page helps improve this situation. This not only targets external links, but also limits the number of embedded scripts. Each <script> tag that the browser encounters during parsing an HTML page may cause a certain latency due to script execution. Therefore, minimizing the latency will significantly improve the overall performance of the page.

This problem is slightly different when processing external link JavaScript files. Considering the extra performance overhead of HTTP requests, downloading a single kb file is faster than downloading 5 20 KB files. That is to say, reducing the number of Chinese and foreign link scripts on the page will improve the performance.

Generally, a large website or application depends on several JavaScript files. You can merge multiple files into one, so that you only need to reference one <script> tag to reduce performance consumption. File merging can be achieved through offline packaging tools or some real-time online services.

Note that placing an embedded script on the <link> referenced external link style sheet will cause page blocking to wait for the style sheet to be downloaded. This is done to ensure that the embedded script can obtain the most accurate style information during execution. Therefore, we recommend that you do not keep the embedded script behind the <link> label.

Non-blocking scripts

Reducing the size of JavaScript files and limiting the number of HTTP requests is not always feasible for a wide range of Web applications or large websites. The richer the functions of Web applications, the more JavaScript code is required. Although downloading a large JavaScript file only generates one HTTP request, the browser will be locked for a long time. To avoid this situation, you need to use some specific technologies to gradually load JavaScript files into the page, so that the browser will not be blocked to some extent.

The secret of a non-blocking script is that JavaScript code is loaded only after the page is loaded. This means that the script will be downloaded after the onload event of the window object is triggered. There are multiple ways to achieve this effect.

Delayed loading script

HTML 4 defines an extension attribute for the <script> tag: defer. The Defer attribute indicates that the script contained in this element does not modify the DOM, so the code can be safely delayed. The defer attribute is only supported by browsers later than IE 4 and Firefox 3.5, so it is not an ideal cross-browser solution. In other browsers, The defer attribute is directly ignored. Therefore, the <script> label is processed in the default mode, which causes blocking. However, this is still a useful solution if your target browser supports it.

Defer attribute usage example

<script type="text/javascript" src="script1.js" defer></script>

The <script> tag with the defer attribute can be placed anywhere in the document. The corresponding JavaScript file will start to be downloaded when the page is parsed to the <script> tag, but will not be executed until the DOM loading is complete, that is, it will not be executed until the onload event is triggered. When a JavaScript file with the defer attribute is downloaded, it does not block other processes in the browser, so such files can be downloaded in parallel with other resource files.

Any <script> element with the defer attribute will not be executed until the DOM is loaded, regardless of the embedded or external link script. The example in listing 5 shows how the defer attribute affects script behavior:

Influence of defer attribute on script Behavior

This Code dialog box appears three times during page processing. The pop-up sequence of browsers that do not support the defer attribute is: "defer", "script", and "load ". In browsers that support the defer attribute, the pop-up sequence is "script", "defer", and "load ". Note that the <script> element with the defer attribute is called before the onload event is triggered instead of being executed after the second element.

If your target browser only includes Internet Explorer and Firefox 3.5, the defer script is indeed useful. If you need to support multiple cross-domain browsers, there are more consistent implementations.

HTML 5 defines a new extended attribute: async for the <script> tag. Similar to defer, defer can load and execute scripts asynchronously without blocking page loading. However, it is worth noting that in the case of async, the JavaScript script will be executed once it is downloaded, so it may not be executed in the original order. If JavaScript scripts are dependent on each other, errors may occur when you use async.

Dynamic script Element

The Document Object Model (DOM) allows you to use JavaScript to dynamically create almost all HTML documents. <Script> elements, like other elements on the page, can be easily created using standard DOM functions:

Use standard DOM functions to create <script> Elements

var script = document.createElement ("script");  script.type = "text/javascript";  script.src = "script1.js";  document.getElementsByTagName("head")[0].appendChild(script);

The new <script> element loads the script1.js source file. This file starts to be downloaded immediately after the element is added to the page. The focus of this technology is that, no matter where the download is started, the download and running of files will not block other page processing processes. You can even put the code in the

When a file is downloaded using a dynamic Script node, the returned code is usually executed immediately (except Firefox and Opera, they will wait until all previous dynamic script nodes are executed ). When the script is of the "self-run" type, this mechanism runs normally. However, if the script only contains interfaces called by other scripts on the page, it may cause problems. In this case, you need to track whether the script is downloaded and prepared properly. You can use the dynamic <script> node to send events to obtain relevant information.

Firefox, Opera, Chorme, and Safari 3 + send an onload event after the <script> node receives the event. You can listen to this event to get the notification prepared by the script:

Load JavaScript scripts by listening to onload events

var script = document.createElement ("script") script.type = "text/javascript";  //Firefox, Opera, Chrome, Safari 3+ script.onload = function(){  alert("Script loaded!"); };  script.src = "script1.js"; document.getElementsByTagName("head")[0].appendChild(script);

Internet Explorer supports another implementation method, which issues a readystatechange event. <Script> An element has a readyState attribute, and its value changes with the process of downloading an external file. ReadyState has five values:

According to Microsoft documents, in the lifecycle of <script> elements, the values of readyState may not all appear, but do not indicate which values will always be used. In practice, we are most interested in the "loaded" and "complete" statuses. Internet Explorer has different final states for the two readyState values. Sometimes the <script> element gets "loader" but never shows "complete ", however, in some other cases, "complete" occurs and "loaded" is not used ". The safest way is to check the two statuses in the readystatechange event, and delete the readystatechange event handle when one of the statuses appears (ensure that the event will not be processed twice ):

Load JavaScript scripts by checking readyState status

var script = document.createElement("script") script.type = "text/javascript";  //Internet Explorer script.onreadystatechange = function(){  if (script.readyState == "loaded" || script.readyState == "complete"){  script.onreadystatechange = null;  alert("Script loaded.");  } };  script.src = "script1.js"; document.getElementsByTagName("head")[0].appendChild(script);

In most cases, you want to call a function to dynamically load JavaScript files. The following functions encapsulate the functions required for standard implementation and IE implementation:

Encapsulate through Functions

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); }

This function receives two parameters: the URL of the JavaScript file and a callback function triggered when the JavaScript reception is complete. Attribute check is used to determine which event to monitor. In the last step, set the src attribute and add the <script> element to the page. ThisloadScript()Function usage:

LoadScript () function usage

loadScript("script1.js", function(){  alert("File is loaded!"); });

You can dynamically load many JavaScript files on the page, but note that the browser does not guarantee the order of file loading. Among all mainstream browsers, only Firefox and Opera ensure that scripts are executed in the specified order. Other browsers will download and run different code files in the order the server returns them. You can concatenate the download operations to ensure their order, as shown below:

Load multiple JavaScript scripts using the loadScript () function

loadScript("script1.js", function(){  loadScript("script2.js", function(){  loadScript("script3.js", function(){  alert("All files are loaded!");  });  }); });

This code starts to load script2.js only after script1.js is available. It starts to load script3.js only after script2.js is available. Although this method is feasible, it is still troublesome to download and execute many files. If the order of multiple files is very important, it is better to connect these files into a file in the correct order. Independent files can download all the code at a time (because this is asynchronous, there is no loss to using a large file ).

Dynamic Script Loading is the most common mode for non-blocking JavaScript downloads because it can be cross-browser and easy to use.

Use XMLHttpRequest (XHR) object

This technology first creates an XHR object, then downloads the JavaScript file, and then injects JavaScript code into the page with a dynamic <script> element. Listing 12 is a simple example:

Load JavaScript scripts using XHR objects

var xhr = new XMLHttpRequest(); xhr.open("get", "script1.js", true); xhr.onreadystatechange = function(){  if (xhr.readyState == 4){  if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){  var script = document.createElement ("script");  script.type = "text/javascript";  script.text = xhr.responseText;  document.body.appendChild(script);  }  } }; xhr.send(null);

This code sends a GET request to the server to GET the script1.js file. The onreadystatechange event handler checks whether readyState is 4, and then checks whether the HTTP status code is valid (2XX indicates a valid response, and 304 indicates a cache response ). If you receive a valid response, create a new <script> element and set its text attribute to the responseText string received by the server. In this way, a <script> element with Inline code is created. Once a new <script> element is added to the document, the code is executed and ready for use.

The main advantage of this method is that you can download JavaScript code that is not executed immediately. Because the code is returned outside of the <script> label (in other words, it is not subject to the <script> label), it will not be automatically executed after download, so that you can postpone the execution until everything is ready. Another advantage is that the same code does not cause exceptions in all modern browsers.

The main limitation of this method is that JavaScript files must be placed in the same domain as pages and cannot be downloaded from CDN (CDN refers to "Content Delivery Network (Content Delivery Network )", therefore, large web pages generally do not use XHR Script Injection Technology.

Summary

Reduce the impact of JavaScript on performance by the following methods:

The above policies can greatly improve the actual performance of Web websites and applications that require a large amount of JavaScript.

Add js loading functions:

function loadJs(url, callback, charset) {  var head = document.getElementsByTagName("head")[0];  var script = document.createElement("script");  if ( !!charset) script.charset = "utf-8";  script.src = url;  script.onload = script.onreadystatechange = function() {  var f = script.readyState;  if (f && f != "loaded" && f != "complete") return;  script.onload = script.onreadystatechange = null;  head.removeChild(script) if (callback) {  callback() || callback  };  };  head.appendChild(script); }
// Js synchronously load function getScripts (I, linkArray, fn) {env | getEnv (); var script = document. createElement ('script'); script. type = 'text/javascript '; script. src = linkArray [I]; var head = document. head | document. getElementsByTagName ('head') [0]; head. appendChild (script); if (env. ie & 'onreadystatechang' in script &&! ('Draggable' in script) {// use the following method to load the script in IE. onreadystatechange = function () {if (/loaded | complete /. test (script. readyState) {script. onreadystatechange = null; if (I = linkArray. length-1) {if (fn) {fn () ;}} else {getScripts (++ I, linkArray, fn) ;}};} else {script. onload = function () {if (I = linkArray. length-1) {if (fn) {fn () ;}} else {getScripts (++ I, linkArray, fn );}};}}
// Js dependencies are sequentially loaded with getScripts (0, ['HTTP: // caibaojian.com/demo/base.js', 'HTTP: // caibaojian.com/demo/reset.js'], function () {alert ('callback ');});

Well, the above is all about this article. I hope this article will help you in your study or work. If you have any questions, please leave a message.

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.