# 回流(重排)
当render tree中的一部分(或全部)因为元素的 规模尺寸,布局,隐藏等改变而需要重新构建。 这就称为回流(reflow)。
当页面布局和几何属性改变时就需要回流
# 重绘
当render tree中的一些元素需要更新属性, 而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
回流必将引起重绘,而重绘不一定会引起回流
# 触发页面重新布局的属性
- 盒子模型相关属性会触发重布局
- 定位属性及浮动也会触发重布局
- 改变节点内部文字结构也会触发重布局
盒子模型相关属性
- width
- height
- padding
- margin
- display
- border-width
- border
- min-height
定位属性及浮动
- top
- bottom
- left
- right
- position
- float
- clear
文字结构
- text-align
- overflow-y
- font-weight
- overflow
- font-family
- line-height
- vertival-align
- white-space
- font-size
# 只触发重绘的属性
- color
- border-style
- border-radius
- visibility
- text-decoration
- background
- background-image
- background-position
- background-repeat
- background-size
- outline-color
- outline
- outline-style
- outline-width
- box-shadow
# 如何优化
- 避免使用触发重绘,回流的css属性。
- 用translate替代top。 translate不会触发回流。
- 用opacity替代visibility。 opacity不会触发回流和重绘。
将重绘,回流的影响范围限制在单独的图层之内。 给需要频繁更新的元素设置 transtrom, will-change属性,这时会新建一个图层。 他们的回流重绘不会影响其他图层。
不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className
div.width = '100px';
div.height = '100px';
div.top = '100px';
.action {
width:'100px';
height:'100px';
top: '100px';
}
div.className = 'action';
把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow), 然后你修改100次,然后再把它显示出来. 因为修改display:none 的元素不会触发回流重绘。
不要在循环里读取位置属性,例如offsetHeight,offsetWidth, clientHeight, clientWidth.
let doms = [];
for(var i = 0; i < doms.length; i++) {
let clientHeight = doms[i].clientHeight;
}
- 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
- 动画实现的速度的选择
- 对于动画新建图层
- 使用 transform:translateZ(0) transform:translate3d(0,0,0) 启用 GPU 硬件加速.