在讨论回流与重绘以前,咱们要知道:浏览器
HTML
解析成DOM
,把CSS
解析成CSSOM
,DOM
和CSSOM
合并就产生了Render Tree
。RenderTree
,咱们就知道了全部节点的样式,而后计算他们在页面上的大小和位置,最后把节点绘制到页面上。Render Tree
的计算一般只须要遍历一次就能够完成,但table
及其内部元素除外,他们可能须要屡次计算,一般要花3倍于同等元素的时间,这也是为何要避免使用table
布局的缘由之一。一句话:回流必将引发重绘,重绘不必定会引发回流。缓存
当Render Tree
中部分或所有元素的尺寸、结构、或某些属性发生改变时,浏览器从新渲染部分或所有文档的过程称为回流。布局
会致使回流的操做:性能
DOM
元素CSS
伪类(例如::hover
)一些经常使用且会致使回流的属性和方法:字体
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color
、background-color
、visibility
等),浏览器会将新样式赋予给元素并从新绘制它,这个过程称为重绘。优化
回流比重绘的代价要更高。动画
有时即便仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。code
现代浏览器会对频繁的回流或重绘操做进行优化:队列
浏览器会维护一个队列,把全部引发回流和重绘的操做放入队列中,若是队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样能够把屡次回流和重绘变成一次。图片
当你访问如下属性或方法时,浏览器会马上清空队列:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
width
、height
getComputedStyle()
getBoundingClientRect()
由于队列中可能会有影响到这些属性或方法返回值的操做,即便你但愿获取的信息与队列中操做引起的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。
table
布局。DOM
树的最末端改变class
。position
属性为absolute
或fixed
的元素上。CSS
表达式(例如:calc()
)。style
属性,或者将样式列表定义为class
并一次性更改class
属性。DOM
,建立一个documentFragment
,在它上面应用全部DOM操做
,最后再把它添加到文档中。display: none
,操做结束后再把它显示出来。由于在display
属性为none
的元素上进行的DOM
操做不会引起回流和重绘。