In the defer and async features of JavaScript script loading and execution in browser environment, we study the timing of execution of delay scripts (defer) and asynchronous scripts (async), browser support, browser bugs, and other details. In addition to the defer and async features, dynamic scripting and Ajax scripting injections are two common ways to create non-blocking scripts. In general, both of these methods can achieve the effect that script loading does not affect page parsing and rendering. But in different browsers, the timing of the scripts created by the two technologies is somewhat different, and today we're going to look at the features of scripts injected with dynamic scripting technology and Ajax.
Code Preparation:
We add dynamic scripts using the Loadscript function in section 2.3 of code Execution order for JavaScript script loading and execution in browser environment, and use the Loadxhrscript function in section 2.4 of this article to implement AJAX script injection. We put both of these functions in the util.js.
In addition, the version of Chrome used in this article is 47.0.2526.80,firefox version is 43.0.4,opera version 30.0.1835.125.
1 Dynamic scripts
1.1 Execution timing problems for dynamic scripts
We add three external JS files on the basis of 2.3 demo in the defer and async features of JavaScript script loading and execution in browser environment:
Dynamic1.js
Test + = "I am the head external dynamic script \ n";
Dynamic2.js
Test + = "I am the body external dynamic script \ n";
Dynamic3.js
Test + = "I am the bottom external dynamic script \ n";
1.1.1 DEMO1: A preliminary study of the execution time of dynamic scripts
The code for HTML is:
<! DOCTYPE html>
<html>
<head>
<meta charset = "UTF-" />
<title> Dynamic Script Test </ title>
<script src = "http://lib.sinaapp.com/js/jquery/../jquery-...min.js"> </ script>
<script src = "util.js"> </ script>
<script type = "text / javascript"> var test = ""; </ script>
<script>
loadScript ("dynamic.js");
</ script>
<script>
test + = "I am a head internal script \ n";
</ script>
<script src = ". js" type = "text / javascript"> </ script>
</ head>
<body>
<button id = "test"> click it </ button>
<script>
loadScript ("dynamic.js");
</ script>
<script src = ". js" type = "text / javascript"> </ script>
</ body>
<script>
loadScript ("dynamic.js");
</ script>
<script src = ". js" type = "text / javascript"> </ script>
<script>
$ (function () {
test + = "I am a script in DOMContentLoaded \ n";
})
window.onload = function () {
test + = "I'm a script in window.onload \ n";
var button = document.getElementById ("test");
button.onclick = function () {
console.log (test);
}
}
</ script>
In our code, we have added 3 dynamic script files to HTML
Note: The results of Firefox and Opera may change
From the example above, we can see that in different browsers, the timing of the execution of dynamic scripts is relatively large, but the following two points can be clear:
[1] A dynamic script does not block subsequent scripts, that is, latency, but this delay does not necessarily last until all normal scripts have been executed, and there is no guarantee that the delay can be deferred to domcontentloaded.
[2] The sequence of dynamic script execution is not guaranteed, which is explained in detail in http://www.jb51.net/article/77920.htm this article and several subsequent articles
As you can see from this demo, dynamic script execution time is quite uncertain, although in DEMO1, dynamic scripts are executed after domcontentloaded events, but it does not mean that dynamic scripts do not block domcontentloaded. Let's look through DEOM2:
1.1.2 DEMO2: Blocking of domcontentloaded by dynamic scripts
We modified the 27th line in the DEMO1 to:
We use the code execution sequence of JavaScript script loading and execution in browser environment To delay the return of the 3.js by 5 seconds, delayfile.php we know that if it is a defer delay script, no matter how long the normal external script is delayed, the defer script will be executed after the normal external script, but the dynamic script is not, so let's look at the order in which the modified code is executed in the browser:
Note: The results of Firefox and Opera may change
As you can see, when a normal script is loaded for a long time, the execution of the dynamic script is significantly ahead, both in IE and in Chrome, Firefox and Opera, before domcontentloaded, so we can make a preliminary judgment The timing of the execution of the dynamic scripts is uncertain and the timing of the execution of the different browsers varies, but the overall should be after the code is loaded and there is no time for the JavaScript code to execute in the thread, but different browsers have different grasp of the time.
Therefore, it is also uncertain whether dynamic scripts will block domcontentloaded, because dynamic scripts may or may not be executed before the domcontentloaded is triggered. And since ie<=8 does not support real domcontentloaded events, jquery also simulates the occurrence of the event in Ie<=8 (the next one is devoted to domcontentloaded events), To some extent it will also affect the execution of our code above.
1.1.3 DEMO3: Dynamic scripting and defer
We know that the defer script has a relatively clear execution time, that is, after the page parsing is complete, loading and executing before the domcontentloaded trigger, in fact, there is no connection between the two in the execution time, but in the actual experiment, it is found that Dynamic scripts may execute before or after defer scripts, but they do not interrupt the execution of defer scripts, and we introduce the defer and async characteristics of JavaScript script loading and execution in browser environment In section 2.3 of the demo in the defer script, modify the HTML code as follows:
<! DOCTYPE html>
<html>
<head>
<meta charset = "UTF-" />
<title> Dynamic Script Test </ title>
<script src = "http://lib.sinaapp.com/js/jquery/../jquery-...min.js"> </ script>
<script src = "util.js"> </ script>
<script>
$ (function () {
test + = "I am a script in DOMContentLoaded \ n";
})
window.onload = function () {
test + = "I'm a script in window.onload \ n";
var button = document.getElementById ("test");
button.onclick = function () {
console.log (test);
}
}
</ script>
<script type = "text / javascript"> var test = ""; </ script>
<script>
loadScript ("dynamic.js");
</ script>
<script>
test + = "I am a head internal script \ n";
</ script>
<script src = "defer.js" type = "text / javascript" defer = "defer"> </ script>
<script src = ". js" type = "text / javascript"> </ script>
</ head>
<body>
<button id = "test"> click it </ button>
<script>
loadScript ("dynamic.js");
</ script>
<script src = "defer.js" type = "text / javascript" defer = "defer"> </ script>
<script src = ". js" type = "text / javascript"> </ script>
</ body>
<script>
loadScript ("dynamic.js");
</ script>
<script src = "defer.js" type = "text / javascript" defer = "defer"> </ script>
<script src = ". js" type = "text / javascript"> </ script>
</ html>
Note: The execution results in firefox and opera may change
We added a few defer scripts, and look at the execution results in each browser:
It can be seen from the experimental results that the execution timing of dynamic scripts is not directly related to defer scripts. On the surface, it seems that in CHROME and firefox, the delay script is always executed before the dynamic script. "Asynchronously loading scripts)" mentioned that "ScriptDOM and defer can be executed at the same time, and their priorities are different in different browsers. In Firfox and Chrome, ScriptDOM has lower priority than defer, and in The situation is the opposite in IE. "In fact, this priority should not exist. We only need to add a load delay to the defer script, and then the execution of the dynamic script will precede the defer script.
1.2 Summary of Dynamic Script Execution Problems
Let's summarize the problems with the execution of dynamic scripts:
[1] First of all, dynamic scripts can indeed delay the execution of scripts to a certain extent, but due to the uncertainty of the timing of the execution of dynamic scripts, the effect of this delay is unknown.
[2] Secondly, the execution order of dynamic scripts does not necessarily follow the order of addition. This is one of the larger problems of dynamic script technology. The simplest solution is to use a callback function to monitor the loading status of the script and load it in a script. After that, add the next script dynamically.
[3] There is no exact timing for the execution of dynamic scripts. When the script element is added to the DOM through methods such as appendChild, insertBefore, etc., the JS script will be loaded. The execution of the script should be at a certain time after the end of loading. Different browsers handle this timing quite differently. For example, in IE, it should adopt the strategy of executing as soon as possible, that is, find the opportunity to execute the code as soon as possible after the end of loading.
[4] The dynamic script may be executed before or after the DOMContentLoaded is triggered, so it is not possible to determine whether it will block DOMContentLoaded. In general, dynamic scripts will block window.onload, but there will also be dynamic scripts that are executed after window.onload is triggered, so that window.onload will not be blocked.
2 Ajax injection script
2.1 Ajax injection script execution timing issues
Ajax script injection technology has two modes: synchronous loading and asynchronous loading. The case of synchronous loading is relatively simple. The loading and execution of the script will block the execution of subsequent code until the injected code is loaded and executed. We mainly discuss the situation in asynchronous mode:
2.1.1 DEMO4: A Preliminary Study of Ajax Injection Script Execution
We add 3 more external files:
ajax1.js
test + = "I am a head external AJAX script \ n";
ajax2.js
test + = "I am a body external AJAX script \ n";
ajax3.js
test + = "I am the bottom external AJAX script \ n";
The HTML code is:
<! DOCTYPE html>
<html>
<head>
<meta charset = "UTF-" />
<title> Ajax Script Test </ title>
<script src = "http://lib.sinaapp.com/js/jquery/../jquery-...min.js"> </ script>
<script src = "util.js"> </ script>
<script type = "text / javascript"> var test = ""; </ script>
<script>
$ (function () {
test + = "I am a script in DOMContentLoaded \ n";
})
window.onload = function () {
test + = "I'm a script in window.onload \ n";
var button = document.getElementById ("test");
button.onclick = function () {
console.log (test);
}
}
</ script>
<script>
loadXhrScript ("ajax.js", true);
</ script>
<script>
test + = "I am a head internal script \ n";
</ script>
<script src = ". js" type = "text / javascript"> </ script>
</ head>
<body>
<button id = "test"> click it </ button>
<script>
loadXhrScript ("ajax.js", true);
</ script>
<script src = ". js" type = "text / javascript"> </ script>
</ body>
<script>
loadXhrScript ("ajax.js", true);
</ script>
<script src = ". js" type = "text / javascript"> </ script>
</ html>
In this code, we added a total of 3 injection scripts inside the <head> tag, inside the <body> tag, and outside the <body> tag. Through the normal introduction of the script as a reference, we take a look at the Results of the:
Note: The execution results in firefox, opera, and IE may change
From this execution result, we can see that the execution timing of the Ajax injection script has greater uncertainty. In fact, similar to the dynamic script, the loading process of the Ajax injection script is asynchronous, so the time to complete the loading The first is uncertain, and the second, when the browser executes the loaded code after the script is loaded, is also uncertain. For the execution timing of the Ajax injection script in asynchronous mode, we summarize it as follows:
[1] Ajax-injected scripts also have a certain delay, but similar to dynamic scripts, the delay time is uncertain.
[2] The execution order of Ajax injection scripts is out of order. Although the example in DEMO4 seems that the injected scripts are executed in the added order, as long as you understand the asynchronous and dynamic script execution order issues, you should be able to understand this. a little.
[3] The execution timing of the Ajax injection script is also uncertain, which is related to the loading time of the script and the processing mechanism of the browser.
[4] Due to the above points, the Ajax-injected script may block DOMContentLoaded or window.onload.