回流(reflow)是页面中元素的尺寸,布局,隐藏或重新构建,这个称为回流(回流会阻塞用户在浏览器中的操作)。因为回流可能导致整个dom树的重新构造,所以是性能的一大杀手。回流必将引起重绘,而重绘不一样引起回流。但是回流是自上而下的,所以下不触犯上,我们可以在最后面修改信息,这样对全局影响较少。
参考网站
回流何时发生
1.添加或删除DOM元素
2.元素位置改变
3.元素尺寸改变(边距,填充,边框,宽度,高度)
4.元素内容改变(文本改变,图片大小改变而引起的计算值和高度改变)
5.页面渲染初始化
6.浏览器窗口改变(resize触发时)
7.fixed定位的元素,在拖动滚动条的时候会一直回流
8.offset相关属性计算
9.设置style的值
重绘
说白了就是更改元素的背景颜色,字体颜色一类的,重绘只影响元素的外观,风格,其不影响布局
如何减少回流、重绘
var s = document.body.style;
s.padding = "2px"; // 回流+重绘
s.border = "1px solid red"; // 再一次 回流+重绘
s.color = "blue"; // 再一次重绘
s.backgroundColor = "#ccc"; // 再一次 重绘
s.fontSize = "14px"; // 再一次 回流+重绘
// 添加node,再一次 回流+重绘
document.body.appendChild(document.createTextNode('abc!'));
避免回流
一. CSS中避免回流
1.尽可能在DOM树的最末端改变class
2.避免设置多层内联样式
3.动画效果应用到position属性为absolute或fixed的元素上
4.牺牲平滑度换取速度
5.避免使用table布局
6.避免使用CSS的JavaScript表达式
二. JS操作避免回流
1.避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性。
2.避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。
3.也可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。(visibility: hidden占位,所以会造成回流)
4.避免循环读取offsetLeft等属性。在循环之前把它们存起来。
5.绝对定位具有复杂动画的元素。绝对定位使它脱离文档刘,否则会引起父元素及后续元素大量的回流。
借鉴来源
很多数据时需要进行操作大量的DOM,可以使用以下方法(避免回流和重绘) createDocumentFragment()
function addDivs(element) {
var div;
// Creates a new empty DocumentFragment.
var fragment = document.createDocumentFragment();
for (var i = 0; i < 20; i ++) {
div = document.createElement('a');
div.innerHTML = 'Heya!';
fragment.appendChild(div);
}
element.appendChild(fragment);
}
window.requertAnimationFrame(addDivs)
页面重绘时,会通知window.requertAnimationFrame
具体可查看
优点:
1.将每一帧的DOM操作(回流,重绘,重排)集中起来,在一次回流或重绘中完成
2.CPU,GPU,内存使用量低
3.页面不激活,方法不调用
如有问题,请及时反馈。