3、DOM Tree 和样式结构体组合后构建 render tree, render tree 类似于DOM tree,但区别很大,render tree 能识别样式,render tree 中每个NODE都有自己的 style,而且 render tree不包含隐藏的节点 (比如display:none 的节点,还有 head 节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到 render tree中。注意 visibility:hidden 隐藏的元素还是会包含到 render tree中的,因为 visibility:hidden 会影响布局(layout),会占有空间。根据CSS2的标准,render tree 中的每个节点都称为Box (Box dimensions),理解页面元素为一个具有填充、边距、边框和位置的盒子。
一旦 render tree 构建完毕后,浏览器就可以根据 render tree 来绘制页面了。
回流与重绘
当 render tree 中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
当 render tree 中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如 background-color。则就叫称为重绘。
说到这里大家都知道回流比重绘的代价要更高,回流的花销跟 render tree 有多少节点需要重新构建有关系,假设你直接操作 body,比如在 body 最前面插入1个元素,会导致整个 render tree 回流,这样代价当然会比较高,但如果是指 body 后面插入1个元素,则不会影响前面元素的回流
testOneByOne 函数改变3次color,其中每次改变后调用getComputedStyle,读取属性值(按我们上面的讨论,这里会引起队列的 flush),testAll 同样是改变3次color,但是每次改变后并不马上调用getComputedStyle。 我们先点击Test One by One按钮,然后点击 Test All,用dynaTrace监控如下: