概念
重排(回流):当某个元素的几何属性发生了变化,浏览器需要重新计算元素的几何属性,并使渲染树中受到影响的部分失效,重新构建渲染树,这个过程称为重排。
重绘:当某个元素的外观发生变化(不影响元素的几何属性)时,浏览器只需要根据元素的新属性进行重新绘制,使元素呈现新的外观,这个过程称为重绘。
注意:
- 每个页面在初次加载时,都需要进行一次重排
- 重绘不一定引起重排,重排一定会引起重绘
触发时机
重排:
- 初始化页面
- 添加或删除可见的dom元素
- 改变元素的位置
- 改变元素的尺寸(包括外边距、边框、内边距、宽高等几何属性)
- 改变浏览器窗口大小
- 设置style属性
- 激活css伪类
- 改变文字大小
- 改变内容(输入内容或改变图片大小)
在获取某些属性值时,也会触发重排,包括:
offsetTop、offsetLeft、offsetWidth、offsetHeight
scrollTop、scrollLeft、scrollWidth、scrollHeight
clientTop、clientLeft、clientWidth、clientHeight
getComputedStyle()
引起重绘的属性:
- color
- text-decoration
- outline
- background、background-image、background-position、background-repeat、background-size
- border-style、border-radius
- box-shadow
- opacity
- visibility
优化策略
浏览器自身优化:
浏览器会维护一个队列,把所有引起重排和重绘的操作放入这个队列,等队列中的操作达到一定数量或达到一个时间间隔,浏览器就会清空队列,将多次重排和重绘变成一次重排与重绘。
当获取某些布局信息(offset等)时,浏览器会强制刷新队列,以确保返回正确的值。
减少重排与重绘:
- 设置样式时,避免使用style内联样式,尽量在class中设定样式后修改dom的className
- 避免使用table布局
- 避免使用css的js表达式
- 避免将dom节点的属性放在一个循环里当作变量
- 避免在布局信息改变时做查询
- 优化元素的动画,将position属性修改为fixed或absolute,使其脱离文档流,减少对其他元素的影响
- 离线操作(先将display设置为none后再进行后续操作)
- 添加节点时使用DocumentFragment或cloneNode,减少重排与重绘