涉及到操作大量Dom节点及其样式时,有时感觉画面不顺畅,殊不知浏览器亚历山大了。所以我们心里面一定得清楚 Reflow(回流)、Repaint(重绘)。
浏览器根据每个Dom节点的样式,包括(大小,颜色,位置等等),计算出各个节点应该在页面上展示的位置,占据的空间,这个过程可以称之为Reflow(回流);当节点的位置,空间确定好以后,浏览器便把这些节点按照各自的样子绘制在页面上,这个过程称之为Repaint(重绘);
触发Reflow
- Dom节点的添加、修改(内容)、删除( Reflow + Repaint)
- 操作 class 属性
- 设置 style 属性的值
- 读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE))
看来我们操作Dom节点,基本上都会触发Reflow,触发Reflow必然也会触发Repaint。而Reflow是影响性能的关键。因此我们要想办法,尽量减少reflow的次数。
触发Repaint
只要修改Dom节点,影响了其外观样式,就会触发Repaint。
性能优化---避免频繁操作document上的节点
- 先将节点从document中删除,修改后再把节点放回原来的位置
- 先将节点的display设置为none,修改后再把节点的display修改为原来的值
- 如需创建多个Dom节点,可以使用DocumentFragment
性能优化---集中修改样式
- 尽可能少的修改元素style上的属性
- 尽量通过修改className来修改样式
- 通过cssText属性来设置样式值
性能优化---缓存layout值
每次读取元素的offsetWidth、offsetHeight等属性,浏览器都会重新计算,如果不需要时时获取最新状态,可以将其值存放在变量中。
性能优化---使节点脱离文档流
将元素的position设置为absolute和fixed,可以使元素从Dom树结构中脱离出来独立的存在,而浏览器在需要渲染时只需要渲染该元素以及位于该元素下方的元素。
操作Dom节点,任重而道远!