自从我阅读/了解 CSSOM 以来,直到今天,这个问题的答案对我来说都很清楚。我似乎无法找到最初的文章,但它通过示例非常清楚地解释了 JavaScript 执行被推迟到 CSSOM 从所有 <style>
构建时执行。和 <link>
<head>
中的标签(不申请者除外,以@media
查询为准)。
或者至少那是我当时的看法,直到今天我都没有理由怀疑它。
这似乎得到了 this sub-chapter 中粗体声明的支持。网络基础/性能,来自谷歌:
... the browser delays script execution and DOM construction until it has finished downloading and constructing the CSSOM.
然而,这一说法受到了与另一位 SO 用户在 this answer 下就此主题进行的友好聊天的严重质疑。我提供了,他在其中提出了以下内容来证明相反的情况:
<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 构建完成),在构建 CSSOM 之前和执行 <script>
之前,页面会空白 10 秒。那会评论 <link />
out 并允许页面呈现。
如果他是对的,那么 js 会按要求运行,<link />
请求永远不会离开,因为它现在是评论。
惊喜:
- 页面立即呈现。 他是对的!
- 但是
<link />
请求离开,浏览器选项卡显示加载图标 10 秒。 我也是对的!还是我?我很困惑,这就是我......
任何人都可以阐明这一点吗?怎么回事?
与document.write
有关系吗?
是否与加载 .php
有关?文件而不是 .css
?
如果有任何不同,我在 Ubuntu 上的 Chrome 中进行了测试。
我恳请链接可靠的(重新)资源或提供 Eloquent 示例/测试来支持您可能考虑提供的任何答案。
最佳答案
这句话是对的,但它意味着如果您先放置样式表,然后放置脚本,则在下载并解析样式表之前,脚本不会执行。看这个例子:
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 并不是对所有样式表都一次性完成,而是一个渐进的过程——当浏览器遇到一个样式表时,它会下载它、解析并下一步移动。也可能浏览器首先列出所有 CSS 资源并将它们添加到下载队列,甚至在执行任何脚本之前。这可以解释为什么即使脚本注释了 link
标记也会发出请求。
关于javascript - JavaScript 的执行是否会延迟到 CSSOM 构建完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44375406/