一、是什么?
重绘:当某个元素的字体颜色等不影响布局的属性变化时,不需要重新构建渲染树,只需直接重新绘制页面即可;
回流:当某个元素的大小、位置发生了变化时,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树;
回流必将引起重绘,重绘不一定会引起回流
tips:当浏览器第一次加载资源时,确定节点的大小和位置称为布局
。
浏览器在加载了一部分资源时,进行了渲染,当继续加载资源时,可能会对前面加载过的资源进行了修改,这可能就会发生回流和重绘。
二、什么导致?
很多种用户操作都可触发重排。例如:调整浏览器窗口的大小、使用涉及计算出的样式的 JavaScript 方法、在 DOM 中添加或移除元素,以及更改某个元素的类,等等。
- 调整窗口大小
- 更改字体
- 添加或删除样式表
- 内容更改,例如用户键入文本
- 输入框
- 激活CSS伪类,例如:hover(在IE中激活同级的伪类)
- 操作类属性
- 操纵DOM的脚本
- 计算offsetWidth和offsetHeight
- 设置style属性的属性
以上这些操作都会触发页面的回流或重绘。
三、如何减少?
从上面的表格中可以清楚地看到,并非对 JavaScript 样式做出的所有更改都会导致在所有浏览器中进行重排,而且执行重排所需的时间也不尽相同。此外,新型浏览器在重排用时方面表现得更出色,这也是比较显而易见的。
下面是一些简单的准则,可帮助您尽可能缩短在网页中进行重排的用时:
- 非必要,避免使用表格进行布局。
- 尽可能减少 CSS 规则的数量,并移除未使用的 CSS 规则。
- 使用
style.cssText="xxx"
代替style.width="xxx"
,或添加class一次性更改。 - 如果您想进行复杂的渲染更改(例如动画),使用 position-absolute 或 position-fixed 来实现。
- 避免频繁读取计算属性
offsetWidth
和offsetHeight
等,如果确实需要多次使用,就用一个变量缓存起来 - 避免使用不必要且复杂的 CSS 选择器(尤其是后代选择器
h1 em {color:red;}
),因为此类选择器需要耗用更多的 CPU 处理能力来执行选择器匹配。 - 减少不必要的 DOM 深度。在 DOM 树中的一个级别进行更改可能会致使该树的所有级别(上至根节点,下至所修改节点的子级)都随之变化。这会导致花费更多的时间来执行重排。
四、回流可视化
五、参考文章
# Reflows & Repaints: CSS Performance making your JavaScript slow?