定义
- 重绘:当元素的一部分属性发生改变,如外观、背景、颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制,使元素呈现新的外观叫做重绘。
- 重排(回流):当 render 树中的一部分或者全部因为大小、边距、位置等问题发生改变而需要 DOM 树重新计算的过程
重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)
如何避免
- 需要要对元素进行复杂的操作时,可以先隐藏(display:"none"),操作完成后再显示
- 需要创建多个 DOM 节点时,使用
DocumentFragment创建完后一次性的加入 document - 缓存 Layout 属性值,如:
var left = elem.offsetLeft;这样,多次使用 left 只产生一次回流 - 尽量避免用 table 布局(table 元素一旦触发回流就会导致 table 里所有的其它元素回流)
- 避免使用 css 表达式(expression,例如
background-color: expression( (new Date()).getHours()% 2 ? "#B8D4FF" : "#F08A00");),因为每次调用都会重新计算值(包括加载页面) - 尽量使用 css 属性简写,如:用 border 代替 border-width, border-style, border-color
- 批量修改元素样式:elem.className 和 elem.style.cssText 代替 elem.style.xxx
浏览器对重绘重排的优化
当操作中存在很多重绘重排的时候,浏览器会维护一个队列,把所有会引起重绘重排的操作放到这个这个队列中,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会 flush 队列,进行一个批处理,这样就会让多次重绘重排变成一次重绘重排。