当前位置:优学网  >  在线题库

DOMContentLoaded在谷歌和火狐浏览器上的执行问题

发表时间:2022-05-27 09:46:30 阅读:52

正在测试CSS会不会阻塞DOM解析,这里模拟样式延时加载:
<link rel="stylesheet" type="text/css" href="style.php">

<?php
// 通过PHP模拟样式延时加载
sleep(5);
header('Content-Type: text/css');
echo 'div{color: red}';

当分别在谷歌和火狐上运行时,DOMContentLoaded的执行不一样。

谷歌:

火狐:

通过上面的测试,是不是可以说明在谷歌浏览器上会阻塞,而在火狐上不阻塞。
或是不同的内核有不同的机制?

🎖️ 优质答案
  • 首先来看标准https://html.spec.whatwg.org/...

    The DOMContentLoaded event fires after the transition to "interactive" but before the transition to "complete", at the point where all subresources apart from async script elements have loaded.

    标准里写得比较清楚。DOMContentLoaded事件的触发取决于文档准备状态的变化,它是在2个状态之间的(即不是即时的)。当DOMContentLoaded触发时,所有除了异步脚本元素<script async />的子资源都应该已经加载完了。
    根据以上描述,DOMContentLoaded事件应该在样式表被加载完才触发。
    但我们去查询标准的变更历史可以发现,这段标准描述存在了非常长的时间。浏览器的发展是非常迅速的,虽然标准本身的描述(不知道什么原因)未经过改变,但至少浏览器都是希望能够尽快尽早地允许开发者进行交互。在标准中的流程描述部分,也未提到DOMContentLoaded事件的具体触发时机,所以就取决于各内核中自身实现的差异了。
    其实这个问题一直都是存在的,而且各版本的内核处理起来可能不尽相同。一些实验表明,如果一个网页文档只加载了样式表,那么样式表的加载就不会阻塞DOMContentLoaded事件的触发;而当样式表引用之后紧跟(同步)脚本时,会阻塞DOMContentLoaded事件的触发。
    这看起来更像是浏览器为了优化,而在仅加载样式表的情况下,提前触发了DOMContentLoaded事件;或进一步说明DOMContentLoaded事件的触发,是和脚本息息相关的。后一种推断似乎更为可靠,因为标准中关于DOMContentLoaded事件的描述中明确提到相关的就是脚本。
    从工作机制上,我们也不难推测出,当仅有样式表需要加载时,网页文档可以先行被解析成DOM树,因为样式表对应的解析成CSSOM的过程与DOM解析过程相互独立,只在最后合成阶段有关系,所以可以并行进行。但当样式表之后有脚本需要执行时,因为脚本可能修改DOM或者需要获取DOM上的样式,所以必须依赖DOM树和CSSOM树全部解析完成(且关联)。因此,如果样式表的加载后如果跟了脚本,就一定会使得DOMContentLoaded延后。

    1. 首先不同的内核会有不同机制,这也正常
    2. css 阻塞带来的问题是首屏渲染和最大内容渲染,这两点好像都不受 DOMContentLoaded 影响,所以可能在这里表现没什么差异,于是开发商就不是很关注
  • 相关问题