前端:页面重排(Reflow)与重绘(Repaint)

前段时间有人我问过我重排(Reflow)与重绘(Repaint)的问题,这里写一篇文章描述一下重排与重绘的区别与优化手段,加深理解。

先科普一下HTML DOM基础知识:

HTML DOM,HTML Document Object Model(HTML文档对象模型)的缩写,HTML DOM 定义了访问和操作 HTML 文档的标准。

W3C对HTML DOM的解释:

1.HTML 的标准对象模型
2.HTML 的标准编程接口
3.W3C 标准

HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准。

Firefox、Chrome和Safari是基于两种渲染引擎构建的,Firefox使用Geoko——Mozilla自主研发的渲染引擎,Safari和Chrome都使用webkit。

我们参考webkit的渲染流程:

前端:页面重排(Reflow)与重绘(Repaint)

解释:

HTML->HTML Parser -> DOM Tree: 解析html,创建DOM Tree,即浏览器将HTML解析成树形的数据结构。

Style->CSS Parser->Style Rules: 解析css,创建样式规则,其实也是将css解析成树形的数据结构。

Attachment->Render Tree->layout: 连接DOM节点与CSS Rules以构生成Render Tree,在render树的基础上进行布局, 计算每个节点的几何结构,这里发生的就是重排(Reflow)。

painting->Display: 绘制,按照算出来的规则绘制样式,显示内容。

Reflow:当涉及到DOM节点的布局属性发生变化时,就会重新计算该属性,浏览器会重新描绘相应的元素,此过程叫回流(Reflow)也叫重排。
Repaint:当影响DOM元素可见性的属性发生变化 (如 color) 时, 浏览器会重新描绘相应的元素, 此过程称为重绘(Repaint)。

因此重排必然会会引起重绘。

浏览器在处理重排时,会递归处理DOM节点,所以导致重排的成本高于重绘,我们只需避免重排即可,引起重排的操作:

1.调整窗口大小
2.字体大小
3.样式表变动
4.元素内容变化,尤其是输入控件
5.CSS伪类激活(:hover、:active等等),在用户交互过程中发生
6.DOM操作,DOM元素增删、修改
7.width, clientWidth, scrollTop等布局宽高的计算

这么看,我们只要避免两种操作即可达到性能优化:

1.避免大量的DOM操作
2.避免过多DOM布局属性的计算

细分:

1.不要直接读取style属性逐条修改保存。应该集中修改样式,譬如直接修改className。
2.创建div,设置display:none,然后将它所有的DOM操作全部应用上,最后再添加到html文档里,修改display,显示出来。
3.避免频繁读取元素几何属性(例如scrollTop)。
4.绝对定位具有复杂动画的元素。绝对定位使它脱离文档流,避免引起父元素及后续元素大量的回流。

后面了解到更多时,再补充。

相关推荐