为什么在DOMContentLoaded之前发生First Paint

时间:2015-12-15 12:38:10

标签: google-chrome google-chrome-devtools domcontentloaded

我正在深入研究Google Chrome附带的性能工具,因为我正试图了解性能改进技术。我正在玩Timeline选项卡,我发现在我的页面 First Paint 事件发生在 DOMContentLoaded 事件之前。我读了一些文章,据说当浏览器开始向用户显示内容的第一时刻必须在 DOMContentLoaded 之后。有人可以解释一下这是真的吗?

3 个答案:

答案 0 :(得分:8)

DOMContentLoaded表示解析器已完成将HTML转换为DOM节点并执行任何同步脚本。

这并不妨碍浏览器呈现不完整的DOM / CSSOM树。事实上,在javascript查询计算CSS属性的情况下,它必须能够执行回流。如果它可以在不完整的树上进行回流,它也可以渲染它们。

这也适用于从服务器流式传输的大型文档。用户在完成加载之前就已经可以开始阅读它了。

重要的是要理解整个解析/评估/呈现过程是流处理管道,其中一些部分甚至是并行/推测性地完成的。管道的后期阶段不会等待前面的阶段完成,而是在输出到达时立即处理它们,并在有足够的信息可用于下一个增量时立即处理它们。

E.g。解析器在处理其所有属性之前显然无法发出Element节点,但它仍然可以在处理其子树时发出节点。并且渲染器可以在没有子节点的情况下渲染节点。并且它可以用不完整的样式呈现,以便稍后进行回流,例如,当javascript插入另一个样式表时,或者只是因为尚未插入的子节点影响它的呈现方式。

http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#The_main_flow

  

了解这是一个渐进的过程非常重要。对于   更好的用户体验,渲染引擎将尝试显示   屏幕上的内容尽快。它不会等到所有   在开始构建和布局渲染树之前解析HTML。   在处理过程中,将解析和显示部分内容   继续保持来自的其他内容   网络

答案 1 :(得分:0)

好问题!据我所知,情况并非总是这样。浏览器需要绘制的是渲染树,这意味着它需要DOM和CSSOM,但重点是像解析器阻塞Java脚本或渲染阻止CSS这样可以阻止此过程的障碍。但是你的问题是关于DOMContentLoaded的,如果你在http://www.w3.org/TR/html5/syntax.html#the-end中阅读为用户代理定义的步骤,特别是第4步,你会看到只要没有剩下的脚本可以执行就会触发这个事件但是如果用脚本标记脚本怎么办?通过执行此操作延迟或异步您承诺脚本不会在CSSOM上查询。这是我从虚拟样本注释中捕获的时间线,我将java脚本标记为延迟:TimeLine Example在此图表中,您可以看到第一个绘图是在DCL之前! 这也是关于分析Ilya Grigorik撰写的关键渲染路径的好文章

答案 2 :(得分:0)

当html中有<script defer>时,将在DOMContentLoaded之前进行第一次绘制。如MDN中所述

具有defer属性的脚本将阻止触发DOMContentLoaded事件,直到脚本加载并完成评估为止。

具有defer属性的脚本不会阻止解析和绘画。 下图显示了我在chrome中使用和未使用<script defer>的html页面进行测试的结果

带有<script defer>的HTML页面 enter image description here

没有<script defer>的HTML页面 enter image description here