Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is JavaScript execution deferred until CSSOM is built or not?

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.

like image 950
tao Avatar asked Oct 17 '22 11:10

tao


1 Answers

This quote is true, but it means that if you place your style sheet first, and a script after it, the script will not execute until the style sheet is downloaded and parsed. See this example:

test.php:

<?php
sleep(5);
header('Content-Type: text/css');
echo 'body {background-color: red;}';

index.html:

<link rel="stylesheet" href="test.php">
<script>console.log('done');</script>

The console.log call won't be executed until background color changes to red.

This leads to the conclusion that building CSSOM isn't done once for all style sheets, but it's a gradual process – when browser encounters a style sheet, it downloads it, parses, and moves next. Also probably browser first makes a list of all CSS resources and adds them to the download queue, even before executing any scripts. That would explain why the request is made even though the link tag is commented by a script.

like image 92
Michał Perłakowski Avatar answered Oct 21 '22 07:10

Michał Perłakowski