关键字:DOM、CSSOM、layout、paint
大家都了解浏览器加载网页的时候首先解析DOM和CSSOM,碰到js会先去下载js并执行。本文会详细描述浏览器执行过程。
浏览器渲染页面前需要先构建 DOM 和 CSSOM 树。因此,我们需要确保尽快将 HTML 和 CSS 都提供给浏览器。
那什么是DOM ?
转换: 浏览器从磁盘或网络读取 HTML 的原始字节,并根据文件的指定编码(例如 UTF-8)将它们转换成各个字符。
令牌化: 浏览器将字符串转换成 W3C HTML5 标准规定的各种令牌,例如,“”、“”,以及其他尖括号内的字符串。每个令牌都具有特殊含义和一组规则。
词法分析: 发出的令牌转换成定义其属性和规则的“对象”。
DOM 构建: 最后,由于 HTML 标记定义不同标记之间的关系(一些标记包含在其他标记内),创建的对象链接在一个树数据结构内,此结构也会捕获原始标记中定义的父项-子项关系:HTML 对象是 body 对象的父项,body 是 paragraph 对象的父项,依此类推
什么又是CSSOM?
在浏览器构建我们这个简单页面的 DOM 时,在文档的 head 部分遇到了一个 link 标记,该标记引用一个外部 CSS 样式表:style.css。由于预见到需要利用该资源来渲染页面,它会立即发出对该资源的请求。
与处理 HTML 时一样,我们需要将收到的 CSS 规则转换成某种浏览器能够理解和处理的东西。因此,我们会重复 HTML 过程,不过是为 CSS 而不是 HTML:
CSS 字节转换成字符,接着转换成令牌和节点,最后链接到一个称为“CSS 对象模型”(CSSOM) 的树结构内:
CSSOM 为何具有树结构?为页面上的任何对象计算最后一组样式时,浏览器都会先从适用于该节点的最通用规则开始(例如,如果该节点是 body 元素的子项,则应用所有 body 样式),然后通过应用更具体的规则(即规则“向下级联”)以递归方式优化计算的样式。
以上面的 CSSOM 树为例进行更具体的阐述。span 标记内包含的任何置于 body 元素内的文本都将具有 16 像素字号,并且颜色为红色 — font-size 指令从 body 向下级联至 span。不过,如果某个 span 标记是某个段落 (p) 标记的子项,则其内容将不会显示。
渲染树、布局及绘制
CSSOM 树和 DOM 树合并成渲染树,然后用于计算每个可见元素的布局,并输出给绘制流程,将像素渲染到屏幕上。优化上述每一个步骤对实现最佳渲染性能至关重要。
1、DOM 树与 CSSOM 树合并后形成渲染树。
2、渲染树只包含渲染网页所需的节点。
3、布局计算每个对象的精确位置和大小。
4、最后一步是绘制,使用最终渲染树将像素渲染到屏幕上。
第一步是让浏览器将 DOM 和 CSSOM 合并成一个“渲染树”,网罗网页上所有可见的 DOM 内容,以及每个节点的所有 CSSOM 样式信息。
为构建渲染树,浏览器大体上完成了下列工作:
1、从 DOM 树的根节点开始遍历每个可见节点。
2、某些节点不可见(例如脚本标记、元标记等),因为它们不会体现在渲染输出中,所以会被忽略。
3、某些节点通过 CSS 隐藏,因此在渲染树中也会被忽略,例如,上例中的 span 节点---不会出现在渲染树中,---因为有一个显式规则在该节点上设置了“display: none”属性。
4、对于每个可见节点,为其找到适配的 CSSOM 规则并应用它们。
5、发射可见节点,连同其内容和计算的样式。
有了渲染树,我们就可以进入“布局”阶段
计算了哪些节点应该是可见的以及它们的计算样式,但尚未计算它们在设备视口内的确切位置和大小---这就是“布局”阶段,也称为“自动重排”。为弄清每个对象在网页上的确切大小和位置,浏览器从渲染树的根节点开始进行遍历。
布局流程的输出是一个“盒模型”,它会精确地捕获每个元素在视口内的确切位置和尺寸:所有相对测量值都转换为屏幕上的绝对像素。
最后,既然我们知道了哪些节点可见、它们的计算样式以及几何信息,我们终于可以将这些信息传递给最后一个阶段:将渲染树中的每个节点转换成屏幕上的实际像素。这一步通常称为“绘制”或“栅格化”。
布局完成后,浏览器会立即发出“Paint Setup”和“Paint”事件,将渲染树转换成屏幕上的像素
在渲染树构建中,我们看到关键渲染路径要求我们同时具有 DOM 和 CSSOM 才能构建渲染树。这会给性能造成严重影响:HTML 和 CSS 都是阻塞渲染的资源。
1、默认情况下,CSS 被视为阻塞渲染的资源。
2、我们可以通过媒体类型和媒体查询将一些 CSS 资源标记为不阻塞渲染。
3、浏览器会下载所有 CSS 资源,无论阻塞还是不阻塞。
当有js时,又是如何影响页面渲染的呢?
JavaScript 允许我们修改网页的方方面面:内容、样式以及它如何响应用户交互。 JavaScript 会阻止 DOM 构建和延缓网页渲染。
1、JavaScript 可以查询和修改 DOM 与 CSSOM。
2、JavaScript 执行会阻止 CSSOM。
3、除非将 JavaScript 显式声明为异步,否则它会阻止构建 DOM。
JavaScript 在 DOM、CSSOM 和 JavaScript 执行之间引入了大量新的依赖关系,从而可能导致浏览器在处理以及在屏幕上渲染网页时出现大幅延迟:
1、当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行。
2、JavaScript 可以查询和修改 DOM 与 CSSOM。
3、JavaScript 执行将暂停,直至 CSSOM 就绪。
参考文案:
资源加载和页面事件 load, ready, DOMContentLoaded
网友评论