了解重绘和回流吗?分别什么情况会发生?

参考:你真的了解回流和重绘吗

JavaScript——浏览器的重绘与回流
什么是回流,什么是重绘,有什么区别?

1、浏览器渲染过程

在这里插入图片描述

  1. 浏览器把获取到的html代码解析成1个Dom树,DOM树里包含了所有HTML标签,包括display:none隐藏,还有用JS动态添加的元素等
  2. 浏览器把所有样式(主要包括css和浏览器的样式设置)解析成样式结构体
  3. dom tree和样式结构体(cssom)结合后构建渲染树(render tree),render tree能识别样式,且render tree不包含隐藏的节点,比如display:none的节点,还有head节点;visibility:hidden隐藏的元素还是会包含到render tree中的,因visibility:hidden 会影响布局(layout),会占有空间
  4. Layout(回流):根据生成的渲染树,进行回流,得到节点的几何信息(位置,大小)
  5. Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  6. Display:将像素发送给GPU,展示在页面上

2、如何生成渲染树

在这里插入图片描述

  1. 从DOM树的根节点开始遍历每个可见节点
  2. 对于每个可见节点,找到CSSOM树中对应的规则,并应用它们
  3. 根据每个可见节点以及其对应的样式,组合成渲染树

不可见的节点包括哪些?

  • 一些不会渲染输出的节点:script\meta\link等
  • 一些通过css进行隐藏的节点,比如display:none

3、回流

定义: 当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流。每个页面至少需要一次回流,就是在页面第一次加载的时候。
**通过构造渲染树,我们将可见DOM节点和它对应的样式结合起来,可是我们还需要计算它们在设备视口(viewport)内确切位置和大小,这个计算的阶段就是回流。**在回流阶段主要计算节点的位置和几何信息,当页面布局和几何信息发生变化的时候,就需要回流

4、重绘

**定义:**当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局
通过构造渲染树和回流阶段,我们知道了可见节点的样式和具体位置大小等信息,那我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段叫做重绘节点。

5、回流发生场景

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(margin、padding、border、height、width)
  • 内容发生变化,比如文本变化或图片被另一个尺寸不同的图片所替代
  • 页面一开始渲染的时候
  • 浏览器的窗口尺寸发生变化
    回流一定会引发重绘,重绘不一定会回流

6、浏览器的优化机制

大多数浏览器都会通过队列化修改并批量执行来优化重排过程,浏览器会将修改操作放入队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。
但是,当获取布局信息的操作 时,会强制队列刷新!

  • offsetTop offsetLeft offsetWidth offsetHeight
  • scrollTop scrollLeft scrollWidth scrollHeight
  • clientTop clientLeft clientWidth clientHeight
  • getComputedStyle()
  • getBoundingClientRect

以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此当我们需要使用上述属性,可以利用一个局部变量来将这些值缓存起来

7、如何减少回流和重绘

(1) 合并多次对DOM和样式的修改,依次处理,可以使用
  • cssText : el.style.cssText += '...'
  • 修改CSS的class : el.className += 'active'
(2) 批量修改DOM

当需要对DOM进行一系列修改时,如何减少回流重绘次数:

  1. 使元素脱离文档流
  2. 对其进行多次修改
  3. 将元素带回文档中

如何让DOM元素脱离文档流?

  1. 隐藏元素,应用修改,重新显示(会在展示和隐藏节点的时候,产生两次重绘)
  2. 使用文档片段在当前DOM之外构建一个子树,再把它拷贝回文档
  3. 将原始元素拷贝到一个脱离文档的节点中,修改节点后,再替换原始的元素
(3)避免触发同步布局事件

利用一个变量来保存属性值,例如:const width = box.offsetWidth

(4)对于复杂的动画效果,使用绝对定位让其脱离文档流
(5)CSS3硬件加速(GPU加速)

常见的触发硬件加速的css属性:

  • transform
  • opacity
  • filters
  • Will-change
    使用css3硬件加速,可以让上述这些动画不会引起回流重绘,但是对于动画的其他属性,比如background-color,还是会引起回流重绘的

缺陷

  1. 如果为太多元素使用css3硬件加速,会导致内存占用较大,会有性能问题
  2. 在GPU渲染字体会导致抗锯齿无效,因为GPU和CPU算法不同

猜你喜欢

转载自blog.csdn.net/weixin_43912756/article/details/108317440