我们知道浏览器在解析文档时,会经历以下步骤:
- 将
HTML解析为DOM,将CSS解析为CSSOM,DOM和CSSOM合并生成Render Tree - 然后根据
Render Tree将节点绘制在页面上
所谓回流是当元素尺寸、结构或者某些属性发生改变时,浏览器重新部分或者全部渲染文档的过程。
所谓重绘是指元素样式发生改变但并未改变其在文档流中的位置。
回流(Reflow)
我们理解了回流之后再看看哪些操作会导致浏览器回流:
- 浏览器窗口大小发生改变
- 元素尺寸或者位置发生变化
- 元素内容变化
- 元素字体变化
- 添加或删除
DOM - 激活
CSS伪类 - 查询某些属性或调用某些方法:
clientWidth、clientHeight、clientTop、clientLeftoffsetWidth、offsetHeight、offsetTop、offsetLeftscrollWidth、scrollHeight、scrollTop、scrollLeftscrollIntoView()、scrollIntoViewIfNeeded()getComputedStyle()getBoundingClientRect()scrollTo()
重绘(Repaint)
当页面中元素的样式改变并不影响其在文档流中得到位置时,浏览器紧紧将新样式赋给它并重新绘制,这就是重绘。例如color、background-color、visibility
思考
既然这样那么我们如何避免重绘与回流呢?
- 避免使用
table布局 - 将动画效果应用到
position属性为absolute或fixed的元素上,脱离文档流的元素不会引起回流 - 可以使用
tranform属性来设置动画 - 避免频繁操作样式,最好使用
class来更改样式 - 避免频繁操作
DOM,创建一个documentFragment,在它上面进行DOM操作 - 可以先将元素设为
display:none,操作后再把它显示出来。因为在display为none的元素上操作不会引起重绘与回流