渲染流程
- JavaScript: 构建 DOM + CSSOM
- Style: 构建 Render Tree
DOM
Document Object Model 通过在内存中表示文档结构,将网页连接到脚本或编程语言。 DOM 使用逻辑树来表示一个文档结构。树的每一个分之都以一个节点结尾,并且每个节点都包含对象。 DOM 方法允许以编程方式访问树,使用这些方法可以更改文档的结构、样式或内容。DOM 上的节点并不一定总是 HTML 元素,当浏览器创建 DOM 树时,它还将诸如注释、属性、文本之类的内容另存为树中的单独节点。
- 构建 DOM 的过程中遇到不携带
async
或defer
的<script>
标签,浏览器会停止 DOM 的构建,等待 JS 的下载和执行。 - 构建 DOM 的过程中携带
async
的<script>
标签下载完毕后,浏览器会停止 DOM 的构建,等待 JS 的执行。
CSSOM
CSS Object Model 允许通过 JavaScript 操纵 CSS,它非常类似于 DOM。CSSOM 和 DOM 是相互独立的。CSSOM 的构建过程类似于 DOM 的构建,不过它依赖的是样式结构,而不是文档结构。
CSSOM 的构建会阻塞浏览器下载&执行 JS。
Render
Render Tree 是将 DOM 和 CSSOM 结合在一起而生成的树状结构。通过 Render Tree 可以知道在每个节点上应用哪些样式规则,但是无法知道这些节点的确切位置及大小信息。在 Render Tree 被构建出来之前,页面上不会呈现任何内容。
display: none
的元素不会出现在 Render Tree 中。- 伪元素会出现在 Render Tree 中。
Layout
Layout Tree 是在 Render Tree 的基础上,为每个节点计算其布局信息,从而构建出的树状结构。
避免在通过 CSSOM 设置完样式后立刻对其进行访问,因为这样要求浏览器在你访问样式时返回最新的样式信息,相当于要求浏览器立刻进入 layout 阶段,从而造成不必要的性能损耗(本来可以在下一帧再更新样式的)。
Paint
在这一阶段需要了解两个概念:layer 和 rasterization。Layer 让浏览器知道以何种顺序去渲染相互层叠的元素,同时帮助浏览器在网页的整个生命周期中更有效执行的 paint 操作。Rasterization 是对每一个 layer 进行栅格化,使得浏览器以更高效的方式进行 paint 操作。
Compositing
利用计算好的 layer 和每一层 layer 内的栅格,组合出 viewpoint 内应该展示的页面。
first paint
为了更好的用户体验,浏览器不一定非要等到 DOM 和 CSSOM 构建完,才开始页面的渲染。可以参考 Chrome的First Paint 的思路自己在浏览器的 performance 面板中观察下实际的效果。
最佳实践是将 <link rel="stylesheet">
标签放在 <head>
中,将 <script>
标签放在 </body>
前。当然如果你为 <script>
标签添加 async
或 defer
属性的话,将它们放在 <head>
中也是可以的。
详细的原理可以参考 How the browser renders a web page? — DOM, CSSOM, and Rendering。
优化方法
- 使用
requestAnimationFrame()
代替setTimeout()
和setInterval()
。 - 避免 long task 的出现。
- 使用 Web Worker。
- 减少样式选择器的复杂度。
- 避免 强制同步布局
参考文献
- Critical rendering path
- Populating the page: how browsers work
- How the browser renders a web page? — DOM, CSSOM, and Rendering
- Inside look at modern web browser (part 3)
- Rendering Performance
- Critical Rendering Path
- How CSS works: Parsing & painting CSS in the critical rendering path
- The Secrets of the CSSOM & Why You Should Care
- Software vs. GPU Rasterization in Chromium
- Accelerated Rendering in Chrome
- Chrome的First Paint