目的
为了提高页面性能,因为重排的消耗较大而且直接影响用户界面,它们将会给响应式网站以及 web APP 造成较大的影响。
定义
重绘[repaints]
重绘是指元素外观的改变所触发的浏览器行为,例如,color/visibility/outline/background-color。等属性引起的元素外观的改变。
回流[reflows]
回流又叫重排,是指浏览器计算页面的全部或部分布局所做的处理。调整浏览器窗口大小,使用伪类(比如 :hover),以及使用JavaScript 操作DOM,影响到页面布局事件的发生,就会导致重排。
同步重排[synchronous reflows]
Web 控制台可以通过记录重排事件来显示出这个重排消耗的时间,如果是由 JavaScript 触发的重排,这个时间是指同步重排(synchronous reflows)时消耗的时间。
重排的原因
- 调整窗口大小
- 字体的大小
- 触发元素的伪类(:hover)
- dom元素的增加、删除,大小改变
- 其他的改动scrollTop、scrollLeft、offsetWidth等的值
解决方案
- 避免使用css的JavaScript表达式(仅IE浏览器)
- 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值。
因为它们已经脱离了正常文档流,动画效果应用到它们的元素上,不影响其他元素的布局,所它他们只会导致重新绘制,而不是一个完整回流。消耗会低一些。 - 避免使用table布局,
表格中某一个单元格内容过宽,而引起其他列大小的改变,就会使布局发生改变,而引起其他节点的重排 - 牺牲平滑度
Opera建议牺牲平滑度换取速度,每次1像素移动一个动画,但此动画及随后的回流使用了100%的CPU,动画就会看上去是跳动的,因为浏览器正在与更新回流做斗争,动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动。 - 改变元素的class名,修改元素样式,如下
1
2
3
4
5
6
7
8<style type="text/css">
.normal{width:300px;height:200px;font-size:14px;}
.change{background:red;border:5px solid grey;height:300px;font-size:20px;}
</style>
<div id="box" class="normal">盒子</div>
<script type="text/javascript">
document.getElementById('box').className = 'normal change';
</script> - 避免设置多项内联样式,DOM交互是很慢,交替的修改和读取一个正在被操作元素的样式,每当你在读取前一次修改的样式时都会强制执行了同步重排.尽量不要出现类似如下的写法(推荐5):
1
2
3
4
5
6
7
8<div id="box" class="normal">盒子</div>
<script type="text/javascript">
var box = document.getElementById('box');
box.style.background = 'red';
box.style.border = '5px solid grey';
box.style.height = '300px';
box.style.fontSize = '20px';
</script> - 尽可能在DOM树的里面改变class,可限制回流的范围,使其影响尽可能少的节点。
PS
重绘可能引发回流,回流必定引发重绘