一.重绘
DOM树没有元素增加或删除,只是样式的改变,针对浏览器对某一元素进行单独的渲染,这个过程就叫做重绘。
当盒子的位置、大小以及其他属性,浏览器便把这些都按照各自的特性绘制一遍,将内容呈现在页面中。重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重绘是视觉效果变化引起的重新绘制。比如 color 或者 background 发生了变化,那就该给触发重绘的元素化化妆,化成它想要的样子。
二.回流
当渲染树中一部分,因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就称为回流,每个页面至少需要一次回流,就是在页面第一次加载的时候。
DOM树中的元素被增加或者删除,导致浏览器需要重新的去渲染整个DOM树,回流比重绘更消耗性能,发生回流必定重绘,重绘不一定会导致回流。
在javascript中,回流也叫做重排,是指当渲染树中的一部分或全部因为元素的规模尺寸、布局、隐藏等改变时,浏览器重新渲染部分DOM或全部DOM的过程;简单来说,就是重新排版整个页面
三.重绘和回流的关系:
在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分,该过程称为重绘,因此重排必定会引发重绘,但重绘不一定会引发重排。
四.会导致回流的操作
- 页面的首次刷新
- 浏览器的窗口大小发生改变
- 元素的大小或位置发生改变
- 改变字体的大小
- 内容的变化(如:input框的输入,图片的大小)
- 激活CSS伪类(如:hover)
- 脚本操作DOM(添加或者删除可见的DOM元素)
- 元素位置的改变,或者使用动画
- 填充内容的改变
- 读取某些元素属性
- 增加或者移除样式表
- 操作class属性
- 计算offsetWidth和offsetHeight属性
- 设置 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.渲染完成,呈现页面