浏览器的渲染过程:
1、解析html,生成DOM树,解析css生成CSSOM树2、将DOM树和CSSOM树结合,生成渲染树(Render Tree)
3、Layout(回流):根据生成的渲染树,进行回流,得到节点的几何信息(位置、大小等)
4、Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
5、Display:将像素发给浏览器的GPU(显卡),展示在页面上。
生成渲染树过程具体做的事情:
为了构建渲染树,具体做了以下事情
例如:
1、 从DOM树的根节点开始遍历每个可见节点。
2、 对于每个可见节点,找到CSSOM树中对应的规则,并且应用。
3、 根据每个可见节点以及对应的样式,组合生成渲染树。
注意:渲染树只包含可见的节点。常见的不可见节点有script、meta、link等标签,以及利用css隐藏的节点例如:display:none。但是visibility和opacity隐藏的节点仍然会出现在render tree里面。
回流(重排 Reflow/Layout):
构造完渲染树之后,我们还需要计算它们在设备窗口(viewport)内的确切位置和大小,这个计算阶段属于回流。
重绘(Repaint):
通过构造完渲染树和回流之后,我们知道了哪些节点是可见的,以及可见节点的样式和具体几何信息,那么我们就可以将渲染树的每个节点都转换成屏幕上的实际像素,这个阶段就叫做重绘节点。
什么时候发生回流重绘:
回流:
- 1、添加或者删除可见的dom元素。
- 2、元素的尺寸发生变化(包括外边距、内边距、边框大小、宽高等)。
- 3、内容发生变化,比如文本的变化或者图片被另一个不同尺存的图片代替。
- 4、首页渲染一个会发生回流,不可避免。
- 5、浏览器窗口大小发生变化(因为回流是根据视口的大小来计算元素的位置和大小的)
重绘:
- 1、background改变
- 2、visibility改变
怎么解决:
- 1、分离读写(浏览器自带优化机制:渲染队列,浏览器会将修改放到队列里面等待执行,达到阈值之后会做一次清空队列,回流一次,但是遇到获取布局信息的操作的时候,这个队列会强制刷新,所以在写的操作(设置高度等)中间不要操作读的操作(clientTop、scrollTop等))
- 2、集中样式改写
- 3、文档碎片(document.createDocumentFragment)
- 4、用es6模板字符串来实现文档碎片功能
- 5、css3硬件加速(GPU加速)transfrom/opacity/filters(过滤器)…这些动画不会引起回流重绘。
- 6、牺牲平滑度
- 7、避免table布局
- 8、将复杂的动画脱离文档。