4.渲染树、布局与绘制
一、 什么是渲染树 (Render Tree)?
在浏览器成功构建了DOM树(代表文档结构)和CSSOM树(代表文档样式)之后,它需要将这两者结合起来,才能知道最终要“画”什么东西在屏幕上。这个结合的产物就是渲染树 (Render Tree)。
目的:渲染树是页面所有可见内容的结构化表示。它的任务是确定哪些节点需要被渲染,以及它们应用了哪些样式。
构建过程:
浏览器从DOM树的根节点开始遍历。
对于每个遍历到的节点,它会去CSSOM树中查找匹配的样式规则并应用。
最终,它会为每个可见节点生成一个渲染树上的节点。
与DOM树的区别:渲染树和DOM树不是一一对应的。
不可见元素被忽略:渲染树不包含任何在视觉上不可见的元素。例如:
<head>、<script>、<meta>等本身不产生视觉输出的标签。通过CSS设置了
display: none;的节点(及其所有后代节点)。
注意:通过
visibility: hidden;或opacity: 0;隐藏的元素会出现在渲染树中,因为它们仍然占据着页面空间,只是不可见而已。
简单来说,DOM树是关于“内容和结构”,而渲染树是关于“要画什么以及如何画”。
二、 什么是布局 (Layout / Reflow)?
一旦渲染树构建完成,浏览器就知道需要渲染哪些节点以及它们的样式,但还不知道它们在屏幕上的确切位置和大小。**布局 (Layout)**步骤就是为了计算这些几何信息。
目的:计算出渲染树中每个节点在设备视口(viewport)内的精确位置和尺寸。这个过程也常被称为回流 (Reflow)。
工作流程:
浏览器从渲染树的根节点开始,进行一次遍历。
它将所有元素的大小和位置信息输出为一个“盒模型”(Box Model),这个模型精确地捕捉了每个元素在页面上的位置(x, y坐标)和尺寸(宽度, 高度)。
相对单位(如
%,em,rem,vw)会被计算成屏幕上的绝对像素值
回流 (Reflow):布局是一个从头到尾的完整过程。但是,当页面上某个元素的几何属性(如宽度、高度、边距、边框)发生变化时,可能会影响到其他元素的位置。浏览器需要重新计算受影响部分的布局,这个重新计算的过程就叫做“回流”。回流是一个非常耗费性能的操作,因为一个微小的改动也可能导致整个页面的重新布局。
可以把布局想象成画一张建筑蓝图:虽然你知道需要一扇门和一扇窗户(渲染树),但你需要通过布局来确定门和窗户在墙上的确切尺寸和位置。
三、 什么是绘制 (Paint)?
在布局阶段确定了所有可见元素的确切几何信息后,浏览器终于可以把它们"画"到屏幕上了。这个过程就是绘制 (Paint)。
目的:将渲染树中的每个节点转换为屏幕上的实际像素。
工作流程:
布局阶段结束后,浏览器得到了所有元素的精确“蓝图”。
绘制阶段会遍历渲染树,调用渲染器的绘制函数,将元素的背景、颜色、文字、边框、阴影等所有视觉效果填充到屏幕的对应区域。
图层与合成 (Layers & Compositing):为了提高效率,浏览器并不会把所有东西都画在一个巨大的画布上。它会智能地将页面内容提升到不同的**图层 (Layer)**上。
当某个元素发生变化时(例如一个CSS动画),如果它位于独立的图层上,浏览器就只需要重绘这一个图层,而不需要重绘整个页面。
最后,浏览器会将所有这些独立的图层按照正确的顺序**合成 (Composite)**在一起,形成最终的屏幕画面。
可以把绘制想象成装修工人根据建筑蓝图(布局),用油漆(填充像素)把墙壁刷上颜色、把窗框描上边。