前端:页面重排(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的渲染流程:
解释:
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.绝对定位具有复杂动画的元素。绝对定位使它脱离文档流,避免引起父元素及后续元素大量的回流。
后面了解到更多时,再补充。