什么是重绘 Repaint 和重排 (回流 reflow)
重绘 : 当元素的一部分属性发生改变,如外观,背景,颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制,是元素呈现心得外观叫做重绘
回流 : 当 render 树中得一部分或者全部因为大小边距等问题发生该案而需要DOM树重新计算得过程
具体浏览器解析渲染机制如下所示 :
- 解析HTML,生成DOM树,解析CSS,生成CSSOM树
- 将DOM树和CSSOM树结合,生成渲染(Render Tree)
- Layout(回流) : 根据渲染树以及回流得到得到的几何信息,得到节点的绝对像素
- Display : 将像素发给GPU,展示在页面上
哪些操作会触发
触发回流
- 页面初次渲染
- 浏览器窗口大小改变
- 元素尺寸、位置、内容发生改变
- 元素字体大小变化
- 添加或者删除可见的 dom 元素
- 激活 CSS 伪类(例如::hover)
- 查询某些属性或调用某些方法:
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- getComputedStyle()
- getBoundingClientRect()
- scrollTo()
触发重绘
- 重绘不一定需要回流(比如颜色的改变),回流必然导致重绘(比如改变网页位置)
-
颜色的修改
-
文本方向的修改
-
阴影的修改
如何减少回流和重绘
- 如果想设定元素的样式,通过改变元素的class类名(尽可能在DOM树的最里层)
- 避免设置多项内联样式
- 应用元素的动画,使用position属性的fixed值或absolute值
- 避免使用 table 布局 table 中每个元素的大小以及内容的改动 ,都会导致整个table的重新计算
- 对于那些复杂的动画,对其设置position:fixed/absolute,尽可能地使元素脱离文档流,从而减少对其他元素的影响
- 使用css3硬件加速,可以让transform,opacity,filters,这些动画不会引起回流重绘
- 避免使用css的javascript表达式