一、概念
首先我们要明白的是,页面的显示过程分为以下几个阶段:
reflow:当render树的一部分或者全部因为大小边距等问题发生改变而需要重建的过程,叫做回流
repaint:当诸如颜色背景等不会引起页面布局变化,而只需要重新渲染的过程叫做重绘
通过上述定义,可以很明显看出,重绘的代价要比回流小,毕竟重绘只涉及样式的改变,不涉及到布局。重绘就好像给人染了一个头发,而回流相当于给人做了一次抽脂手术
二、什么会引起回流
这也是网易题目的出法
页面渲染初始化
DOM结构变化,比如删除了某个节点;骨头都被打断了,肯定比抽脂更严重,所以会引发回流
render树变化,比如减少了padding;也就是进行抽脂手术
窗口resize事件触发
最复杂的一种:获取某些属性,引发回流 很多浏览器会对回流做优化,他会等到足够数量的变化发生,在做一次批处理回流。但是除了render树的直接变化。 当获取一些属性时,浏览器为了获得正确的值也会触发回流。这样就使得浏览器的优化失效了
这些属性包括:
①. offsetTop, offsetLeft, offsetWidth, offsetHeight
②. scrollTop/Left/Width/Height
③. clientTop/Left/Width/Height
④. width,height
⑤. 调用了getComputedStyle(), 或者 IE的 currentStyle
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!'));
可以看出,回流一定伴随着重绘,而重绘却可以单独出现
可以理解为,路人甲摔断了腿或者抽脂之后,病怏怏导致头发也变白了(回流+重绘);但是炮灰乙却仅仅是去村口王师傅那里烫了头(重绘)。
回流对性能产生了一定的影响,尽管浏览器机智地帮我们进行了批处理,但是仍然存在着上述诸多阔怕的属性,一获取就回流。怎么解决?
三、减少回流
display:none指的是元素完全不陈列出来,不占据空间,涉及到了DOM结构,故产生reflow与repaint
visibility:hidden指的是元素不可见但存在,保留空间,不影响结构,故只产生repaint