一、重绘(repaint)不一定发生重排(reflow),重排一定会发生重绘
回流会导致渲染树需要重新计算,开销比重绘大,所以我们要尽量避免回流的产生
重排:当渲染树的一部分必须更新且节点尺寸发生变化,浏览器会使渲染树中受到影响的部分实效,并重新构造渲染树。
1、页面首次渲染 首次渲染时,所有组件首次布局,这是开销最大的一次回流
2、浏览器窗口尺寸发生变化
3、元素位置和尺寸发生变化
4、新增或删除可见元素
5、内容发生改变(文字数量或图片大小等)
6、元素字体大小变化
7、激活伪类(如:hover)
8、设置style属性
9、查询某些属性或调用某些方法,如: offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
10、除此之外,当我们调用getComputedStyle方法,或者IE里的currentStyle时,也会触发回流,原理是一样的,都为求一个“即时性”和“准确性”
重绘:元素的样式发生改变时触发的浏览器的行为。浏览器会根据元素的新属性重新绘制。
1、渲染树中的元素的外观、风格发生变化,不会影响布局
2、visibility、outline、背景色、改变字体颜色等属性的变化
下面的代码是影响回流和重绘的:
var s = document.body.style;
s.padding = "2px"; // 回流+重绘
s.border = "1px solid red"; // 再一次 回流+重绘
s.color = "blue"; // 重绘
s.backgroundColor = "#ccc"; // 重绘
s.fontSize = "14px"; // 再一次 回流+重绘
document.body.appendChild(document.createTextNode('abc!'));// 添加node,再一次 回流+重绘
二、减少repaint和reflow
1、不要一条一条的修改DOM的样式,可以先定义好css的class,然后修改DOM的className
2、不要把DOM节点的属性值放在一个循环里当成循环里的变量
3、为动画的HTML元件使用fixed或absolute的position,那么修改它们的css不会发生reflow