今天在看面试题的时候遇到reflow和repaint的问题,以前并没有接触过,所以拿来学习一下~

reflow 和 repaint 会拖慢浏览器的速度,而且用户和Web页面都不能在 reflow 和 repaint 执行时做任何操作和响应

reflow和repaint定义及触发场景

repaint

repaint是重绘,在改变 DOM 元素的视觉效果时触发,即不涉及任何排版布局的问题时触发。

触发场景:

  • opacity
  • text-align/text-decoration
  • color/background-color
  • :hover

repaint发生后浏览器会去 check 这个DOM元素内的所有节点,所以repaint会影响某个DOM进行重绘。

reflow

reflow是回流,在某一个 DOM 元素的位置发生改变后触发,而且它会重新计算所有元素的位置和在页面中的占有的面积,所以reflow的影响比repaint更大,因为它将会影响它所有的children、ancestors及siblings。所以影响是针对整个页面的,整个页面都需要重新渲染。

触发场景:

  • 使用JS改变DOM元素时会触发reflow,即添加(appendChild)、删除(removeChild)DOM元素或者改变DOM元素的可见性(display:none)

  • CSS中width/height/border/margin/padding的改变
  • CSS3 动画(animation)和过渡(transition),动画的每一frame都会触发reflow

  • 读取元素的某些属性(offsetLeft/Top、offsetHeight/Width、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE))时会触发reflow,因为这些属性需要依赖一些元素去计算

  • :hover 引起的元素表现变化

  • 浏览器大小的改变   (resize)

  • 字体大小改变或更换字体   (font)

  • 更换class样式表

如何尽可能的避免触发reflow和repaint,提高性能?

  1. 尽可能的减少DOM元素相互影响

  2. 避免设置内联样式

  3. 尽量简写CSS样式
  4. 删除复杂动画,尽量给动画元素设置position:fixed/absolute,使动画元素从DOM流中独立出来,从而减少对其他元素的影响。同时,尽量牺牲平滑度去满足性能,因为动画精度太强,会造成更多次的repaint/reflow

  5. 避免使用table进行布局:table的每个元素的大小以及内容的改动,都会导致整个table进行重新计算,造成大幅度的repaint或者reflow。改用div则可以进行针对性的repaint和避免不必要的reflow

  6. 避免在CSS中使用运算式:学习CSS的时候就知道,这个应该避免,不应该加深到这一层再去了解,因为这个的后果确实非常严重,一旦存在动画性的repaint/reflow,那么每一帧动画都会进行计算,性能消耗不容小觑。

  7. 减少DOM的层级,减少DOM的数量,DOM数量越少越好
  8. 慎改class!!去改子元素少的DOM的class
  9. 尽量采取批量更新元素样式的方式,比如可以将需要修改的样式集合放在一个class里,将这个class附给元素

关于性能问题还有很多需要说的,之前在准备面试的时候看到Yahoo总结的一些性能提升的方法,要慢慢积累起来!

最近回学校写毕业论文的空档又复习总结了一些比如闭包啊this指向啊作用域啊之类的js的题,明天继续发博~大家晚安~