Consider the following code:
<head>
<style>
.box{
background-color:red;
height:150px;
width:150px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var start = new Date();
while(true) {
var now = new Date();
if (now-start > 10000)
break;
}
console.log('main thread finished');
</script>
</body>
It is a big surprise to me that DOM defers its loading for ten seconds (.box rectangle is appeared after 10 seconds!). Since it comes first ( <div class="box"></div> )
, why is waiting for the script which follows? Any reasonable explanation?
Thank you
"Scripts without async or defer attributes, as well as inline scripts, are fetched and executed immediately, before the browser continues to parse the page." -- from MDN.
So your script stops parsing for 10 seconds. Not to speak about rendering the page. Basically this was done to support immediate html modifications from within the executing script. For example if your script calls for document.write('More html')
it will affect parsing.
By the way executing script has access to the DOM structure that has been already parsed. Consider the following example.
<div class="box">Affected</div>
<script>
[].forEach.call(document.querySelectorAll('.box'), function(box){
box.innerText += '... modified';
});
</script>
<div class="box">Not</div>
To simplify it, JavaScript is single-threaded which means it cannot take care of the DOM model at the same time as taking care of your tiny script. It goes one after another one.
Really comprehensive exmplatantion can be found here.
To avoid the problem of blocked UI, you may be interested in learning about Web Workers.
Because of the way the engine works (single thread) any script execution blocks any progressive rendering in the page below the script
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With