作为一个前端工程师,最常见的运行环境就是浏览器吧。
- 用户在浏览器地址栏中输入 URL 并按下回车键,把 HTTP 请求发送给服务器。
- 浏览器获得并解析服务器的返回内容。
- 浏览器加载 HTML 文件及文件内包含的外部引用及图片,多媒体等资源。
- 浏览器在加载的时候,渲染引擎同时也开始渲染页面。
渲染流程#
- 构建 DOM tree: 从上到下解析 HTML 文档生产 DOM 节点树(DOM tree),也叫内容树(content tree)。
- 构建 CSSOM tree(CSS Object Model):加载解析样式生产 CSSOM tree。
- 构建 render tree:根据 DOM 树和 CSSOM 树生成渲染树(render tree)。渲染树是按照顺序展示在屏幕上的一些列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。
- 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕的正确位置上。
- 绘制(painting):遍历渲染树绘制的所有节点,为每个节点适用对应的样式。
说明:
在构建 CSSOM 树时,会阻塞渲染,直至 CSSOM 树构建完成。并且构建 CSSOM 树是一个十分消耗性能的过程,所以应该尽量保证层级扁平,减少过度层叠,越是具体的 CSS 选择器,执行速度越慢。
当 HTML 解析到 script 标签时,会暂停构建 DOM,完成后才会从暂停的地方重新开始。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件。并且 CSS 也会影响 JS 的执行,只有当解析完样式表才会执行 JS,所以也可以认为这种情况下,CSS 也会暂停构建 DOM。

Reflow(回流、Relayout 重排)#
定义
在渲染树布局完成后,再次操作文档,改变文档的内容或结构,或者元素定位时,会触发回流,即需要重新布局。
触发条件
- DOM 操作,如增加、删除、修改和移动
- 变更内容
- 寄过伪类
- 改变 CSS 样
- 浏览器窗口变化(尺寸变化或者滚动)
Repaint(重绘)#
定义
当我们改变了一部分元素属性时,如背景颜色等,对布局没有影响,但是浏览器会根据新特性重新渲染,这就是重绘。
触发条件
- DOM 的改动
- 改变 CSS 样式
说明:回流的过程一定会伴随着重绘,但是重绘不一定会引起回流。
渲染优化#
回流和重绘都会对影响页面性能,需要尽量减少回流和重绘的次数和缩小它们的影响范围。
推荐以下优化和实践
- HTML 文档结构层次尽量少,最好不要多于 6 层。
- JavaScript 文件尽量后放,放在
</body>前即可。 - 少量首屏样式内联放在 head 标签内。
- 脚本尽量减少 DOM 操作,尽量缓存 DOM 的样式信息。
- 减少通过 JavaScript 代码修改元素样式,尽量使用修改 class 名方式改变样式或者动画。
- 动画尽量使用在绝对定位或固定定位的元素上。