关键渲染路径 (Critical Rendering Path)是什么?
浏览器将 HTML,CSS 和 JavaScript 转换为屏幕上的像素所经历的步骤序列。优化关键渲染路径可提高渲染性能。
关键渲染路径共分五个步骤。
构建DOM -> 构建CSSOM -> 构建渲染树 -> 布局 -> 绘制。
1. 解析 HTML 构建 DOM(DOM 树),并行请求 css/image/js
2. CSS 文件下载完成,开始构建 CSSOM(CSS 树)
3. CSSOM 构建结束后,和 DOM 一起生成 Render Tree(渲染树)
4. 布局(Layout):计算出每个节点在屏幕中的位置
5. 显示(Painting):通过显卡把页面画到屏幕上
理论上的流程图应该是上面部分,但是你别忘了index.html文件有javascript代码所以是下面部分:
通常情况下DOM和CSSOM是并行构建的,但是当浏览器遇到一个script标签时,DOM构建将暂停,直至脚本完成执行。但由于JavaScript可以修改CSSOM,所以需要等CSSOM构建完毕后再执行JS,这就是为什么我们需要把 js 放在页面底部的原因,尽量保证 DOM 树生成完毕再去加载 JS,从而出现这样的效果。
面对上面,我们可以针对dom和cssom进行优化:
- 减少 DOM 树渲染时间(譬如降低 HTML 层级、标签尽量语义化等等)
- 减少 CSSOM 树渲染时间(降低选择器层级等等)
- 减少 HTTP 请求次数及请求大小
- 将 css 放在页面开始位置
- 将 js 放在页面底部位置,并尽可能用 defer 或者 async 避免阻塞的 js 加载,确保 DOM 树生成完才会去加载 JS
- 用 link 替代@import
- 如果页面 css 较少,尽量使用内嵌式
- 为了减少白屏时间,页面加载时先快速生成一个 DOM 树
我们也可以使用js异步加载策略进行优化:
- defer 属性:页面解析完了,脚本顺次执行
- async 属性:谁先加载完就立刻先执行谁
DOM树和渲染树的区别
- 渲染树的重要特性是它仅捕获可见内容,不包括 head 和隐藏元素(display:none),大段文本的每一个行都是独立节点,每一个节点都有对应的 css 属性
- DOM 树与 HTML 标签一一对应,包括 head 和隐藏元素