我正在深入研究 Google Chrome 附带的性能工具,因为我正试图了解性能改进技术。我正在使用 Timeline 选项卡,我发现在我的页面上First Paint事件发生在DOMContentLoaded事件之前。我读了几篇文章,据报道,浏览器开始向用户显示内容的第一个时刻必须是在DOMContentLoaded之后。有人可以解释一下这是真的吗?
3 回答
DOMContentLoaded 表示解析器已完成将 HTML 转换为 DOM 节点并执行任何同步脚本。
这并不排除浏览器呈现不完整的 DOM/CSSOM 树。事实上,它必须能够执行重排,以防 javascript 查询计算 CSS 属性。如果它可以在不完整的树上进行回流,它也可以渲染它们。
这也与从服务器流式传输的大型文档有关。用户可以在它完成加载之前开始阅读它。
重要的是要了解整个解析/评估/渲染过程是一个流处理管道,其中一些部分甚至是并行/推测性完成的。管道的后期阶段不会等待早期阶段完成,而是在输出到达时获取并在有足够信息可用以执行下一个增量时立即处理它们。
例如,解析器显然不能在处理其所有属性之前发出元素节点,但它可以在处理其子树的同时发出节点。并且渲染器可以渲染没有其子节点的节点。并且它可能会以不完整的样式呈现,以便稍后进行重排,例如,当 javascript 插入另一个样式表时,或者仅仅是因为尚未插入的子节点影响了它的呈现方式。
http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#The_main_flow
重要的是要了解这是一个渐进的过程。为了更好的用户体验,渲染引擎会尽量在屏幕上尽快显示内容。在开始构建和布局渲染树之前,它不会等到所有 HTML 都被解析。部分内容将被解析和显示,而该过程将继续处理来自网络的其余内容。
从历史上看(至少在 Firefox 中)曾经有一个初始绘制延迟,在此期间页面不会呈现,直到它准备好或延迟计时器到期。多年来,该延迟的默认设置被反复降低,直到达到 5 毫秒,这小于许多显示器的刷新率间隔(在 60Hz 显示器上为 16 毫秒)。这种行为可能会导致页面仅在 上呈现的不准确印象DOMContentLoaded,但即使在那时,用户仍然会在足够慢的页面上看到部分页面呈现。
好问题!据我所知,情况并非总是如此。浏览器需要绘制的是渲染树,这意味着它需要 DOM 和 CSSOM,但关键是存在诸如解析器阻塞 Java Script 或渲染阻塞 CSS 之类的障碍可以阻止这个过程。但是,如果您阅读了http://www.w3.org/TR/html5/syntax.html#the-end中为用户代理定义的步骤,特别是第 4 步,您将看到此事件被触发,那么您的问题具体是关于 DOMContentLoaded每当没有要执行的脚本时,但是如果您通过这样做将脚本标记为 defer 或 async 怎么办,您保证该脚本不会在 CSSOM 上查询。这是我从我的虚拟示例注释中捕获的时间线,我将 java 脚本标记为延迟:时间线示例在这张图表中,您可以看到第一次绘制在 DCL 之前!这也是 Ilya Grigorik 写的关于分析关键渲染路径的好文章

