首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

怎么减少浏览器的repaint和reflow?(转载)

2012-11-23 
如何减少浏览器的repaint和reflow?(转载)文本内容主要包括以下几点:什么是repaint/reflow?什么情况下会触

如何减少浏览器的repaint和reflow?(转载)

文本内容主要包括以下几点:

  1. 什么是repaint/reflow?
  2. 什么情况下会触发浏览器的repaint/reflow?
  3. 浏览器自身所作的优化
  4. 如何优化你的脚本来减少repaint/reflow?

?

一、什么是repaint/reflow?

页面在加载的过程中,需要对文档结构进行解析,同时需要结合各种各样的样式来计算这个页面长什么样子,最后再经过浏览器的渲染页面就出现了。这整个 过程细说起来还是比较复杂,其中充满了repaint和reflow。对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式 (浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如 颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。

以上提到的只是在页面加载时必然会出现的repaint和reflow,除此之外,在页面加载完成后,用户的一些操作、脚本的一些操作都会导致浏览器发生这种行为,具体在后文阐述。

另外,关于浏览器渲染的更为详细的资料可以参考以下,涵盖了IE以及Firefox:

Understanding Internet Explorer Rendering Behaviour

Notes on HTML Reflow

二、什么情况下会触发浏览器的repaint/reflow?

除了页面在首次加载时必然要经历该过程之外,还有以下行为会触发这个行为:

  • DOM元素的添加、修改(内容)、删除( Reflow + Repaint)
  • 仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)
  • 应用新的样式或者修改任何影响元素外观的属性
  • Resize浏览器窗口、滚动页面
  • 读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、 getComputedStyle()、currentStyle(in IE))

    在继续下面的文章之前,先介绍一款强大的性能分析工具-dynaTrace,借助该功能能够清晰的得到页面中的资源消耗情况,从而对症下药。另外,更细节的方面是它可以跟踪每个函数调用所造成的CPU消耗、Repaint/Reflow。接下来就借助该工具来测试一下以上描述的几点情况。

    DOM元素的增删改

    先看代码

    放大之后来看一下每个事件的repaint/reflow情况:

    增加节点:

    怎么减少浏览器的repaint和reflow?(转载)

    修改节点:

    怎么减少浏览器的repaint和reflow?(转载)

    删除节点:

    怎么减少浏览器的repaint和reflow?(转载)

    图中的绿色部分表示的是reflow和repaint过程,其中比较短的绿条标示的reflow过程,后面长条部分表示 的是repaint过程。从图中可以看出,对DOM节点的增删改都会造成reflow和repaint,由于改动小所以reflow消耗的时间很短,但是 由于repaint是全局的,因此消耗的时间都比较长。

    修改DOM元素前景色

    从上图中可以看到修改字体颜色后,浏览器只有repaint而没有reflow。接下来试试修改背景色:

    由图中可以看出,修改背景色也会造成reflow和repaint。另外,经过测试发现,只要是修改元素的cssText属性,不论它的值是什么,都会导致浏览器reflow和repaint,因此在某些时候选择特定的样式属性赋值会有更好的效果。

    Resize浏览器窗口以及拖动滚动条

    怎么减少浏览器的repaint和reflow?(转载)

    测试中的操作如下:缩小浏览器窗口->放大浏览器窗口->拖动页面滚动条至页面底部。从图中可以看到Resize浏览器窗口以及拖动滚动条都会造成浏览器的repaint,而且CPU的消耗也比较大,尤其是拖动滚动条的时候。

    读取Layout属性

    根据各种参考资料中的描述,在用Javascript读取DOM节点的Layout属性(offsetLeft、offsetTop、 offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left /Width/Height、getComputedStyle()、currentStyle(in IE)) 的时候也会触发repaint,不过在以下的测试例子中并没有发现这一点。

    ?

    三、浏览器优化

    浏览器对于每一个渲染动作并不是立即执行,而是维护了一个渲染任务队列,浏览器会根据具体的需要分批集中执行其中的任务。除了浏览器自身维护的定期调度之外,脚本中的某些操作会导致浏览器立即执行渲染任务,例如读取元素的Layout属性。

    最后读取的渲染图:

    怎么减少浏览器的repaint和reflow?(转载)

    四、如何优化你的脚本来减少reflow/repaint?

    1. 避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行,具体的方法包括但不完全包括以下几种:

    (1). 先将元素从document中删除,完成修改后再把元素放回原来的位置

    (2). 将元素的display设置为”none”,完成修改后再把display修改为原来的值

    (3). 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document

    appendLast:

    怎么减少浏览器的repaint和reflow?(转载)

    2. 集中修改样式

    (1). 尽可能少的修改元素style上的属性

    (2). 尽量通过修改className来修改样式

    (3). 通过cssText属性来设置样式值

    如下的代码中,每一次赋值都会造成浏览器重新渲染,可以采用cssText或者className的方式

    position: absolute

    怎么减少浏览器的repaint和reflow?(转载)

    在postion:relative的测试当中,浏览器在重新渲染时做的工作比position:absolute多了不少。

    参考资料

    Understanding Internet Explorer Rendering Behaviour

    Notes on HTML Reflow

    EFFICIENT JAVASCRIPT

    原文地址 http://varnow.org/?p=232

    ?

热点排行
Bad Request.