如何减少浏览器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元素的增删改

先看代码

HTML:

 
 
这里是第1个节点
这里是第2个节点
这里是第3个节点

Javascript:

        function $(id){
            return document.getElementById(id);
        }
        function addNode(){
            var n = document.createElement('div');
            n.innerHTML = 'New Node';
            $('test1').appendChild(n);
        }
        function modNode(){
            $('test2').innerHTML = 'hello';
        }
        function delNode(){
            $('test3').parentNode.removeChild($('test3'));
        }

在依次点击完每一个按钮后,我们来看看dynaTrace的情况,首先是一目了然的点击事件分布

 

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

 

增加节点:

 

修改节点:

删除节点:

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

 

修改DOM元素前景色

var n = $('colorNode');
n.style.color = 'red';

 

 

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

var n = $('colorNode');
n.style.backgroundColor = 'red';

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

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

 

 

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

读取Layout属性

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

var n = $('colorNode');
var temp = document.documentElement.currentStyle;
temp = n.offsetTop;
temp = n.offsetLeft;
temp = n.offsetWidth;
temp = n.offsetHeight;
temp = n.scrollTop;
temp = n.scrollHeight;
alert(temp);

 

 

 


如何减少浏览器repaint和reflow(上)

如何减少浏览器repaint和reflow(中)

如何减少浏览器repaint和reflow(下)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值