如何减少浏览器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,不过在以下的测试例子中并没有发现这一点。

 

 

 

 


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

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

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

 











本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/744798 ,如需转载请自行联系原作者
相关文章
|
缓存 JavaScript 前端开发
浏览器:重绘(repaint)与回流/重排(reflow)
浏览器:重绘(repaint)与回流/重排(reflow)
170 0
|
缓存 移动开发 JavaScript
浏览器重绘(repaint)重排(reflow)与优化[浏览器机制]
网页生成过程: HTML被HTML解析器解析成DOM 树 css则被css解析器解析成CSSOM 树 结合DOM树和CSSOM树,生成一棵渲染树(Render Tree) 生成布局(flow),即将所有渲染树的所有节点进行平面合成 将布局绘制(paint)在屏幕上 第四步和第五步是最耗时的部分,这两步合起来,就是我们通常所说的渲染。 网上找了一张图片,我加了注释会更直观一些: 渲染: 网页生成的时候,至少会渲染一次。 在用户访问的过程中,还会不断重新渲染 重新渲染需要重复之前的第四步(重新生成布局)+第五步(重新绘制)或者只有第五个步(重新绘制)。 重排比重绘大: 大,在这个语境里的意思
354 0
浏览器重绘(repaint)重排(reflow)与优化[浏览器机制]
|
前端开发 JavaScript
浏览器的回流与重绘 (Reflow & Repaint)
浏览器的回流与重绘 (Reflow & Repaint)
214 0
|
4月前
|
JavaScript 前端开发 数据处理
模板字符串和普通字符串在浏览器和 Node.js 中的性能表现是否一致?
综上所述,模板字符串和普通字符串在浏览器和 Node.js 中的性能表现既有相似之处,也有不同之处。在实际应用中,需要根据具体的场景和性能需求来选择使用哪种字符串处理方式,以达到最佳的性能和开发效率。
132 63
|
4月前
|
算法 开发者
Moment.js库是如何处理不同浏览器的时间戳格式差异的?
总的来说,Moment.js 通过一系列的技术手段和策略,有效地处理了不同浏览器的时间戳格式差异,为开发者提供了一个稳定、可靠且易于使用的时间处理工具。
156 57
|
4月前
|
JSON 移动开发 JavaScript
在浏览器执行js脚本的两种方式
【10月更文挑战第20天】本文介绍了在浏览器中执行HTTP请求的两种方式:`fetch`和`XMLHttpRequest`。`fetch`支持GET和POST请求,返回Promise对象,可以方便地处理异步操作。`XMLHttpRequest`则通过回调函数处理请求结果,适用于需要兼容旧浏览器的场景。文中还提供了具体的代码示例。
在浏览器执行js脚本的两种方式
|
4月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
779 1

热门文章

最新文章