♫【网站优化】Reflow / Repaint

时间:2024-05-27 11:35:20

web移动开发最佳实践之js篇

浏览器的回流与重绘 by 张盛志

DOM性能瓶颈与Javascript性能优化

浏览器的渲染原理简介

其中一个跟浏览器有关的原因,那就是浏览器需要花时间、花精力去渲染。当它发现某个部分发生了变化影响了布局,需要倒回去重新渲染,我们就称这个回退的过程叫Reflow。
只要某些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起这些元素内部、周围甚至整个页面的重新渲染。

Repaint比较好理解,其实就是浏览器根据重新计算的各个属性值对页面的部分元素进行重新绘制。
如果只是改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器Repaint。Repaint的速度明显快于Reflow(在IE下需要换一下说法,Reflow要比Repaint更缓慢-0-)。

引起 Reflow 和 Repaint 的因素

  • Resize浏览器窗口、滚动页面
  • 字体的改变(大小,颜色,行高等)
  • 添加/删除一个样式表
  • 应用新的样式或者修改任何影响元素外观的属性
  • 伪类(例如:hover)
  • DOM元素的添加、修改(内容)、删除
  • 读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、 getComputedStyle()、currentStyle(in IE))

如何尽量减少Reflow 和Repaint

  • 尽可能限制reflow的影响范围。
  • 如果通过设置style属性改变结点样式,每设置一次都会导致一次reflow。所以最好通过设置class的方式。
  • 实现元素的动画,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局。
  • 在效果和性能上取得平衡。
  • 不要用tables进行布局。Table的子元素只要有一个触发了reflow,会导致整个表格的其他元素都发生reflow,而且它产生reflow的时间,是其他block元素的reflow的3倍。在适合使用table的场合,定义table-layout的属性值为auto或fixed,让其一行一行输出。
  • 避免在CSS中使用表达式。如果CSS里有expression,每个expression都会导致CSS重新计算一遍。很多情况下都会触发reflow。
  • 页面上尺寸可以确定的元素,例如图片,文本框等等,最好为其定义高度和宽度。
  • 避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行。
    (1). 先将元素从document中删除,完成修改后再把元素放回原来的位置
    (2). 将元素的display设置为”none”,完成修改后再把display修改为原来的值
    (3). 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document
  • 集中修改样式。
    (1). 尽可能少的修改元素style上的属性
    (2). 尽量通过修改className来修改样式
  • 缓存Layout属性值。这样可以避免每次读取属性时造成浏览器的渲染。