Explain three ways of asynchronous loading of JS in detail

  • 2021-07-26 06:41:58
  • OfStack

1: Synchronous loading

We usually use the most one way.


<script src="http://yourdomain.com/script.js"></script>
<script src="http://yourdomain.com/script.js"></script>

Synchronous mode, also known as blocking mode, will prevent the subsequent processing of the browser and stop the subsequent parsing. Only when the current load is completed can the next step be operated. Therefore, the default synchronous execution is safe. However, if there are some behaviors in js, such as outputting document content, modifying dom, redirecting, etc., the page will be blocked. Therefore, it is recommended to put < script > The label is placed on < body > At the end, so as to minimize page blocking.

2: Asynchronous loading

Asynchronous loading is also called non-blocking loading. When the browser downloads and executes js, it will continue to process subsequent pages. There are three main ways.

Method 1: Also called Script DOM Element


(function(){
  var scriptEle = document.createElement("script");
  scriptEle.type = "text/javasctipt";
  scriptEle.async = true;
  scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
  var x = document.getElementsByTagName("head")[0];
  x.insertBefore(scriptEle, x.firstChild); 
 })();
<async> Attribute is HTML5 Added asynchronous support in. This method is called Script DOM Element  Method. Google Analytics  And  Google+ Badge  All use this asynchronous loading code 
(function(){;
  var ga = document.createElement('script'); 
  ga.type = 'text/javascript'; 
  ga.async = true; 
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
  var s = document.getElementsByTagName('script')[0]; 
  s.parentNode.insertBefore(ga, s); 
})();

However, this loading mode will prevent the trigger of onload event before it is executed, and now many page codes perform extra rendering work when onload is executed, so it will still block the initialization processing of some pages.

Method 2: Asynchronous loading at onload


(function(){
 if(window.attachEvent){
   window.attachEvent("load", asyncLoad);
  }else{
   window.addEventListener("load", asyncLoad);
  }
  var asyncLoad = function(){
   var ga = document.createElement('script'); 
    ga.type = 'text/javascript'; 
    ga.async = true; 
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(ga, s);
  }
)();

This method only puts the method inserted into script in a function, and then executes it in onload method of window, thus solving the problem of blocking onload event trigger.

Note: The difference between DOMContentLoaded and load. The former is that document has been parsed, and dom elements in the page are available, but the pictures, videos, audio and other resources in the page are not loaded, which acts as ready events in jQuery; The difference between the latter is that all resources on the page are loaded.

Method 3: Other methods

Because of the dynamic nature of JavaScript, there are many asynchronous loading methods: XHR Injection, XHR Eval, Script In Iframe, Script defer attribute, document. write (script tag).

XHR Injection (XHR injection): Get JavaScript through XMLHttpRequest, and then create an script element to insert into the DOM structure. ajax Set script. text to responseText returned after successful request.


 // Get XMLHttpRequest Object, consider compatibility. 
  var getXmlHttp = function(){
    var obj;
    if (window.XMLHttpRequest)
      obj = new XMLHttpRequest();
    else
      obj = new ActiveXObject("Microsoft.XMLHTTP");
    return obj;
  }; 
  // Adopt Http Request get Mode ;open() The first of the method 3 Parameters indicate that asynchronous is adopted (true) Or synchronization (false) Deal with 
  var xmlHttp = getXmlHttp();
  xmlHttp.open("GET", "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js", true);
  xmlHttp.send(); 
  xmlHttp.onreadystatechange = function(){
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
      var script = document.createElement("script");
      script.text = xmlHttp.responseText;
      document.getElementsByTagName("head")[0].appendChild(script);
    }
  } 
XHR Eval : With XHR Injection Right responseText The implementation mode is different, directly put responseText Put on eval() Function. 
  // Get XMLHttpRequest Object, consider compatibility. 
  var getXmlHttp = function(){
    var obj;
    if (window.XMLHttpRequest)
      obj = new XMLHttpRequest();
    else
      obj = new ActiveXObject("Microsoft.XMLHTTP");
    return obj;
  }; 
  // Adopt Http Request get Mode ;open() The first of the method 3 Parameters indicate that asynchronous is adopted (true) Or synchronization (false) Deal with 
  var xmlHttp = getXmlHttp();
  xmlHttp.open("GET", "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js", true);
  xmlHttp.send(); 
  xmlHttp.onreadystatechange = function(){
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
      eval(xmlHttp.responseText);
      //alert($);// Can pop up $, Indicate JS Has been loaded in. click If the event is placed in other places, it will go wrong. It should not be loaded yet 
      $("#btn1").click(function(){
        alert($(this).text());
      });
    }
  } 

Script In Irame: Insert an iframe element in the parent window, and then load JS in iframe.


 var insertJS = function(){alert(2)};
  var iframe = document.createElement("iframe");
  document.body.appendChild(iframe);
  var doc = iframe.contentWindow.document;// Get iframe In window To use contentWindow Property. 
  doc.open();
  doc.write("<script>var insertJS = function(){};<\/script><body onload='insertJS()'></body>");
  doc.close();

GMail Mobile: The content of JS in the industry is annotated, so it will not be executed. When necessary, get the content of text in script, remove the annotation, and call eval () for execution.


  <script type="text/javascript"> 
  /* 
  var ... 
  */ 
  </script>

HTML5 New Attributes: async and defer Attributes

defer property: IE 4.0 appears. There will be no document. write and dom modifications in the defer generic declaration script. The browser will download other script with defer attribute in parallel. Without blocking the subsequent processing of the page. Note: All defer scripts must be executed in sequence.


  <script type="text/javascript" defer></script>

async Attribute: New Html5 Attribute. Scripts will be executed as soon as they are downloaded, similar to defer, but there is no guarantee that scripts will be executed in sequence. They will be completed before the onload event.


  <script type="text/javascript" defer></script>

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 that all IE after IE 4 support asynchronous loading.

Without the async attribute, script is immediately fetched (downloaded) and executed, blocking subsequent processing by the browser. If there is an async attribute, script is downloaded and executed asynchronously, while the browser continues subsequent processing.

Summary: For browsers supporting HTML5, only async attributes need to be added to script elements to realize asynchronous loading of JS, and defer attributes need to be added in order to be compatible with the old version of IE; For browsers that do not support Html5 (IE can be implemented with defer), the above methods can be adopted. Basically, the principle is to write script into DOM or execute JS code through eval function. You can put it into anonymous function, execute it in onload, inject it through XHR, create an iframe element, and then insert JS code into iframe.

3: Delayed loading

Some JS code needs to be used in some cases, not when the page is initialized. Delayed loading is to solve this problem. Split JS into many modules, load only the JS that needs to be executed immediately when the page is initialized, and then delay the loading of other JS until the first time it is needed. Similar to delayed loading of pictures.
The loading of JS is divided into two parts: download and execution. Asynchronous loading only solves the problem of downloading, but the code will be executed immediately after downloading, and the browser will be blocked during execution, so it can't respond to any requirements.

Solution: In order to solve the problem of JS delayed loading, asynchronous loading cache can be used, but it is not executed immediately, and it is executed when necessary. How to cache? The JS content is loaded and cached as an Image or Object object, so it is not executed immediately and then executed the first time it is needed.

1: Simulate longer download times:

Use thread to make its sleep1 period of time to perform download operation.

2: Simulate longer JS code execution time


  var start = Number(new Date());
  while(start + 5000 > Number(new Date())){// Execute JS}

This code will make JS execute for 5 seconds to complete!

JS Deferred Load Mechanism (LazyLoad): Simply put, when the browser scrolls to a certain position, it triggers related functions to realize the loading of page elements or the execution of certain actions. How to detect the scroll position of browser? It can be realized by a timer, and whether the function needs to be executed can be judged by comparing the position of the target node of the page and the height of the browser scroll bar at a certain time.


Related articles: