重绘和回流

139 阅读4分钟

一.重绘

DOM树没有元素增加或删除,只是样式的改变,针对浏览器对某一元素进行单独的渲染,这个过程就叫做重绘。

当盒子的位置、大小以及其他属性,浏览器便把这些都按照各自的特性绘制一遍,将内容呈现在页面中。重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。

重绘是视觉效果变化引起的重新绘制。比如 color 或者 background 发生了变化,那就该给触发重绘的元素化化妆,化成它想要的样子。

二.回流

当渲染树中一部分,因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就称为回流,每个页面至少需要一次回流,就是在页面第一次加载的时候。

DOM树中的元素被增加或者删除,导致浏览器需要重新的去渲染整个DOM树,回流比重绘更消耗性能,发生回流必定重绘,重绘不一定会导致回流。

在javascript中,回流也叫做重排,是指当渲染树中的一部分或全部因为元素的规模尺寸、布局、隐藏等改变时,浏览器重新渲染部分DOM或全部DOM的过程;简单来说,就是重新排版整个页面

三.重绘和回流的关系:

在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分,该过程称为重绘,因此重排必定会引发重绘,但重绘不一定会引发重排。

四.会导致回流的操作

  1. 页面的首次刷新
  2. 浏览器的窗口大小发生改变
  3. 元素的大小或位置发生改变
  4. 改变字体的大小
  5. 内容的变化(如:input框的输入,图片的大小)
  6. 激活CSS伪类(如:hover)
  7. 脚本操作DOM(添加或者删除可见的DOM元素)
  8. 元素位置的改变,或者使用动画
  9. 填充内容的改变
  10. 读取某些元素属性
  11. 增加或者移除样式表
  12. 操作class属性
  13. 计算offsetWidth和offsetHeight属性
  14. 设置 style 属性的值

简单理解:影响到布局了,就会有回流

五. CSS中避免重绘、回流

1.尽可能在DOM树的最末端改变class
2.避免设置多层内联样式
3.动画效果应用到position属性为absolute或fixed的元素上
4.避免使用table布局
5.使用CSS3硬件加速,可以让transform、opacity、filters等动画效果不会引起重绘回流

六.  JS操作避免重绘、回流

1.避免使用JS,一个样式修改完接着改下一个样式,最好一次性更改CSS样式,或者将样式列表定义为class的名称
2.避免频繁操作DOM,使用文档片段创建一个子树,然后再拷贝到文档中
3.先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发重绘和回流
4.避免循环读取offsetLeft等属性,在循环之前把它们存起来
5.对于复杂动画效果,使用绝对定位让其脱离文档流,否则会引起父元素及后续元素大量的回流

七.浏览器渲染解析页面完整流程(拓展)

  • 1.先解析HTML,生成DOM树(重要步骤)

  • 2.后解析CSS,生成样式规则

  • 3.根据DOM树与样式规则,得到一颗渲染树Render Tree(重要步骤)

    • DOM树:只有结构没有样式
    • 渲染数:DOM树 + CSS样式 (可以理解为附加了样式的DOM树)
  • 4.渲染引擎开始工作,解析渲染树。

    • 这个步骤发生 回流(又称重排) : 计算节点的尺寸、结构、布局
  • 5.开始绘制

    • 这个步骤发生重绘 : 根据重排结果进行绘制页面
  • 6.渲染完成,呈现页面