回流 reflow
浏览器渲染视图需要计算元素在设备视口(viewport)内的位置和大小,当节点的位置或者大小发生变化时就会触发回流(reflow)。
触发条件:
- 添加或删除可见的 DOM 元素
- 元素的位置或者尺寸发生变化
- 内容发生变化。比如文本变化或图片被另一个不同尺寸的图片替代
- 页面一开始渲染的时候
- 浏览器的窗口尺寸变化
重绘 repaint
改变元素背景色等属性,会使浏览器根据新的属性重新绘制(repaint),使元素呈现新的外观。
回流一定会触发重绘,而重绘不一定会回流
浏览器的优化机制
浏览器会通过队列化修改并批量执行来优化重排过程(batchedUpdates)。
浏览器会将修改操作放入到队列里,直到过一段时间或者操作达到了一个阈值,才清空队列。但是,当你获取布局信息的操作的时候(DOM 操作),会强制队列刷新,比如当你访问以下属性或者使用以下方法:
offsetTop、offsetLeft、offsetWidth、offsetHeight scrollTop、scrollLeft、scrollWidth、scrollHeight clientTop、clientLeft、clientWidth、clientHeight getComputedStyle() getBoundingClientRect()
以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。
因此,在修改样式的时候,最好避免使用上面列出的属性,他们都会刷新渲染队列。如果要使用它们,最好将值缓存起来。