JavaScript 执行是否推迟到 CSSOM 构建完成?

Is JavaScript execution deferred until CSSOM is built or not?

从 read/learned 关于 CSSOM 开始,直到今天,这个问题的答案对我来说都很清楚。我似乎无法找到最初的文章,但它通过示例非常清楚地解释了 JavaScript 执行被推迟,直到 CSSOM 从所有 <style><link> 标签构建在 <head> 中(不适用的除外,基于 @media 查询)。
或者至少那是我当时的看法,直到今天我都没有理由怀疑它。

这似乎得到了 Web 基础/性能 this sub-chapter 中粗体声明的支持,来自 Google:

... the browser delays script execution and DOM construction until it has finished downloading and constructing the CSSOM.

然而,在我提供的 下与另一位 SO 用户就此主题进行的友好聊天对这一说法提出了严重挑战,他在其中提出以下内容来证明相反的情况:

<head>
  <script>document.write("<!--");</script>
  <style> body { background-color: red; } </style>
  -->
</head>

好的,让我们确定一下。让我们用

替换 <style>
<link rel="stylesheet" type="text/css" href="test.php" />

... 并让 test.php 挂起几秒钟:

<?php
sleep(10);
header('Content-Type: text/css');
?>

/* adding styles here would be futile */

如果我是对的(并且 js 执行被推迟到 CSSOM 构建完成),页面会空白 10 秒,然后再构建 CSSOM 和执行 <script> 以评论 <link /> 出来并允许页面呈现。

如果他是对的,那么 js 是 运行,因为它已经满足并且 <link /> 请求永远不会离开,因为它现在是评论。

惊喜:

任何人都可以对此有所了解吗?这是怎么回事?
document.write有关系吗?
它与加载 .php 文件而不是 .css 文件有关吗?


如果有任何不同,我在 Chrome、Ubuntu 上进行了测试。

我恳请链接可靠的(重新)资源或提供 eloquent example/test 来支持您可能考虑提供的任何答案。

这句话是对的,但这意味着如果您先放置样式 sheet,然后放置脚本,则在下载并解析样式 sheet 之前,脚本不会执行。看这个例子:

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>

在背景颜色变为红色之前,不会执行 console.log 调用。

由此得出的结论是,构建 CSSOM 并非针对所有样式 sheet 一次性完成,而是一个渐进的过程——当浏览器遇到样式 sheet 时,它会下载、解析并下一步移动。也可能浏览器首先列出所有 CSS 资源并将它们添加到下载队列,甚至在执行任何脚本之前。这可以解释为什么即使脚本注释了 link 标记也会发出请求。