reflow 就是回流,它的影响比 repaint 大。它会在某一个 DOM 元素的位置发生改变后触发,而且它会重新计算所有元素的位置和在页面中的占有的面积,这样的话将会引起页面某一个部分甚至整个页面的重新渲染。改变某一个元素会影响它所有的子节点 (children)、祖先节点 (ancestors) 及兄弟节点(siblings)。
2.2、repaint 重绘
repaint 就是重绘,它会在你改变 DOM 元素的视觉效果时进行,改变布局时不会触发。比如,opacity, background-color, visibility 和 outline等都会触发,重绘的开销还是比较昂贵的,因为浏览器会在某一个 DOM 元素的视觉效果改变后去 check 这个 DOM 元素内的所有节点。
2.3、reflow 和 repaint 都是浏览器慢的元凶
用户和 Web 页面都不能在 reflow 和 repaint 执行时做任何操作和响应,而且在极端的情况下,CSS 会拖慢 JS 的执行速度,这就是浏览器有的时候就是在操作之后没反应的原因之一。
在 《DOM 是 javaScript 与 HTML 页面进行对话的接口》中, 提到了
reflow
和repaint
会引发浏览器性能问题。本篇主要来讲讲这个。现今的三大框架中,都提倡要避免操作
DOM
,为什么呢?因为操作DOM
会影响性能慢。实际上这个性能不是慢在操作DOM
过程本身,而是操作DOM
之后, 浏览器的渲染引擎基本流程中的reflow
和repaint
要回流和重绘导致的。reflow
和repaint
是浏览器渲染引擎工作流的一部分,所以先来了解一下浏览器渲染引擎一、 渲染引擎(The rendering engine)
浏览器有个叫渲染引擎的组件, 负责显示请求的内容。如果请求的内容是
HTML
,它就负责解析HTML
和CSS
内容,并将解析后的内容显示在屏幕上。渲染引擎的职责就是渲染,即在浏览器窗口中显示所请求的内容。这是每一个浏览器的核心部分,所以渲染引擎也称为浏览器内核。
默认情况下,渲染引擎只可显示
HTML
和XML
文档及图片。不过通过插件(或浏览器扩展程序),浏览器渲染引擎也可以显示其它类型的内容。例如,使用PDF
查看器插件就能显示PDF
文档。2.1、渲染引擎简介
当前流行的
Firefox
、Chrome
和Safari
浏览器是基于两种渲染引擎构建的。Firefox
使用的是Gecko
,这是Mozilla
公司“自制”的渲染引擎。而Safari
和Chrome
(28版本以前)浏览器使用的都是Webkit
。Webkit
是一种开放源代码渲染引擎,起初用于Linux
平台,随后由Apple
公司进行修改,从而支持苹果机和Windows
。有关详情,请参阅 webkit.org。2.2、主流程(The main flow)
渲染引擎获取了文档内容之后,渲染引擎开始正式工作,如下图渲染引擎的基本流程:
渲染引擎解析
HTML
文档,并将文档中的标签转化为dom
节点树,即”内容树”。同时,它也会解析外部CSS
文件以及style
标签中的样式数据。这些样式信息连同HTML
中的”可见内容”一道,被用于构建另一棵树——”渲染树(Render
树)”。渲染树由一些带有视觉属性(如颜色、大小等)的矩形组成,这些矩形将按照正确的顺序显示在频幕上。
渲染树构建完毕之后,将会进入”布局”处理阶段,即为每一个节点分配一个屏幕坐标。
再下一步就是绘制
(painting)
,即遍历render
树,并使用UI
后端层绘制每个节点。图2.2为Webkit 主流程
图2.3为
Mozilla
的Gecko
渲染引擎主流程从图2.2 和图2.3可以看出,虽然
Webkit
和Gecko
使用的术语略有不同,但整体流程还是基本相同的。Gecko
将视觉格式化元素组成的树称为”框架树”(frame
)。每个元素都是一个框架。Webkit
使用的术语是”渲染树”(render
),它由”渲染对象”组成。Webkit
使用的术语是”布局”(layout)
,而Gecko
称之为”重排”(reflow)
。Webkit
称利用dom
节点及样式信息去构建render
树的过程为attachment
,Gecko
在html
和dom
树之间附加了一层,这层称为内容接收器,相当制造dom
元素的工厂。二、reflow 和 repaint
从第一部分的浏览器引擎我们可以看出,
reflow
和repaint
分别在渲染引擎的基本流程的第三步和第四步。2.1、reflow 回流
reflow
就是回流,它的影响比repaint
大。它会在某一个DOM
元素的位置发生改变后触发,而且它会重新计算所有元素的位置和在页面中的占有的面积,这样的话将会引起页面某一个部分甚至整个页面的重新渲染。改变某一个元素会影响它所有的子节点 (children)、祖先节点 (ancestors) 及兄弟节点(siblings)。2.2、repaint 重绘
repaint
就是重绘,它会在你改变DOM
元素的视觉效果时进行,改变布局时不会触发。比如,opacity
,background-color
,visibility
和outline
等都会触发,重绘的开销还是比较昂贵的,因为浏览器会在某一个DOM
元素的视觉效果改变后去check
这个DOM
元素内的所有节点。2.3、reflow 和 repaint 都是浏览器慢的元凶
用户和
Web
页面都不能在reflow
和repaint
执行时做任何操作和响应,而且在极端的情况下,CSS
会拖慢JS
的执行速度,这就是浏览器有的时候就是在操作之后没反应的原因之一。绘制(repaint)是一个耗时的过程,然而布局(layout/reflow)是一个更耗时的过程,我们无法确定
layout/reflow
一定是自上而下或是自下而上进行的,甚至一次layout/reflow
会牵涉到整个文档布局的重新计算。但是
layout/reflow'是肯定无法避免的,所以我们主要是要最小化
layout/reflow`的次数。Reference