domLoading
The time when the browser starts to parse the dom tree
domInteractive
Indicates that the browser has parsed the dom tree.
domContentLoaded
The synchronized JS has been executed.
Need to explain a little more here:
Since synchronous JS will block the analysis of Dom, in the case of synchronous JS, the difference between domInteractive and domContentLoaded is not much.
If the defer attribute is added to JS, the time difference between domInteractive and domContentLoaded depends on the download and execution time of JS. defer JS tells the browser that this JS will be executed after domInteractive. See http://www.w3.org/TR/html5/syntax.html#the-end . Once defer JS is executed, domContentLoaded will be triggered.
If the JS attribute is async, then domContentLoaded and domInteractive are almost the same, because the js parsing will not block the dom, nor the domContentLoad event.
onload
The elements on the page have been loaded. Including all CSS, JS, Image and so on.
Some small experiments
The following examples all use blocking as an experiment, and you can access the online version .
Question 1: Will synchronized JS write to JS script through document.write delay DomContentLoaded?
Conclusion: Yes. As you can see from the example, DomContentLoaded must wait for the synchronously written JS file to be written before it is triggered.
Code:
<html>
<head>
</head>
<body>
<script>
document.write('<script src="t/wait-3s.js"' + '></' + 'script>');
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
timeline:
Question 2: Will synchronous JS dynamic insertion of defer JS delay DomContentLoaded?
Conclusion: comContentLoaded will not be delayed, but onload time will be blocked. It needs to be added that even if the JS without defer is dynamically inserted, DomContentLoaded will not be delayed.
For the following code:
<html>
<head>
</head>
<body>
<script>
var script = document.createElement('script');
script.src= "/t/wait-2s.js";
script.defer = true;
document.head.appendChild(script);
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
The timeline is as follows: (blue is the main document, yellow line is the JS file)
Question 3: If the script (sync / defer / async) is dynamically inserted at the time of domContentLoaded, will the onload event be blocked?
Conclusion: (Sync / defer / async) will block the onload event.
Code (take defer as an example):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', function(){
var script = document.createElement('script');
script.src= "/t/wait-2s.js";
script.defer = true;
document.head.appendChild(script);
});
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
timeline:
The two small experiments above should be proved in the specification: Spin the event loop until the
set of scripts that will execute as soon as possible
andthe list of scripts that will execute in order as soon as possible
are empty.
Question 3: If the CSS / picture / iframe is inserted dynamically during domContentLoaded, will the onload event be blocked?
Conclusion: Will block. Dynamically inserted images / CSS will block the onload event, iframe will not.
Code (take image as an example):
<html>
<head>
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', function(){
var img = document.createElement('img');
img.src= "/t/wait-2s.png";
document.body.appendChild(img);
/*
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "t/wait-3s-red.css";
document.body.appendChild(link);
*/
/*
var iframe = document.createElement('iframe');
iframe.src = "t/wait-3s.html";
document.body.appendChild(iframe);
*/
});
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
result:
[More to be added ...]