The answer to this question has been clear to me ever since I read/learned about CSSOM, until today. I can't seem to be able to find the initial article, but it explained quite clear, with examples, that JavaScript execution is deferred until CSSOM is built from all <style>
and <link>
tags in <head>
(except those not applying, based on @media
queries).
Or at least that's what I made of it at the time and I had no reason to doubt it until today.
This seems to be backed up by the bold-ed statement in this sub-chapter of Web Fundamentals / Performance, from Google:
... the browser delays script execution and DOM construction until it has finished downloading and constructing the CSSOM.
However, this statement was seriously challenged by a friendly chat on the subject with another SO user under this answer I provided, in which he proposed the following to prove the opposite:
<head>
<script>document.write("<!--");</script>
<style> body { background-color: red; } </style>
-->
</head>
Ok, so let's make sure. Let's replace the <style>
with
<link rel="stylesheet" type="text/css" href="test.php" />
... and make test.php
hang for a few seconds:
<?php
sleep(10);
header('Content-Type: text/css');
?>
/* adding styles here would be futile */
If I am right (and js
execution is deferred until CSSOM is built), the page hangs blank for 10 seconds, before building CSSOM and before executing the <script>
that would comment the <link />
out and would allow the page to render.
If he is right, the js is ran as it's met and the <link />
request never leaves, because it's a comment by now.
Surprise:
- the page renders right away. He's right!
- but the
<link />
request leaves and the browser tab shows a loading icon for 10 seconds. I'm right, too! Or am I? I'm confused, that's what I am...
Could anyone shed some light into this? What is going on?
Does it have to do with document.write
?
Does it have to do with loading a .php
file instead of a .css
?
If it makes any difference, I tested in Chrome, on Ubuntu.
I kindly ask linking a credible (re)source or providing an eloquent example/test to back-up any answer you might consider providing.
console.log(document.documentElement.style.width);
– Unwillingconsole.log(document.documentElement.style.width);
outputs nothing (an empty line). However, console.log('nothing') outputs what you'd expect:nothing
. And it happens right away. – Activate