浏览器工作原理 - 浏览器渲染流程(一)

164 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」6的第天,点击查看活动详情

由于渲染机制过于复杂,所以渲染模块在执行过程中会被划分为很多子阶段,输入的 HTML 经过这些子阶段,最后输出像素。我们把这样的一个处理流程叫做渲染流水线,其大致流程如下图所示:

Image.png

🐼按照渲染的时间顺序,流水线可分为如下几个子阶段:

  1. 构建 DOM 树
  2. 样式计算
  3. 布局阶段
  4. 分层
  5. 绘制
  6. 分块
  7. 光栅化
  8. 合成。

我们可以把渲染流水线当作一个车间流水线,我们只关注输入输出,中间的处理当作黑盒即可;不去关注过程

构建 DOM 树

由于浏览器无法直接理解和使用 HTML,所以需要将 HTML 转换为浏览器能够理解的结构——DOM 树。

Image [2].png

HTML解析器:接收到HTML字节流时,首先要经过渲染引擎的HTML解析器,将HTML字节流转换成DOM树结构。

构建 DOM 树的输入内容是一个非常简单的 HTML 文件,然后经由 HTML 解析器解析,最终输出树状结构的 DOM。

可以看到,DOM 和 HTML 内容几乎是一样的,但是和 HTML 不同的是,DOM 是保存在内存中树状结构,可以通过 JavaScript 来查询或修改其内容。

样式计算(Recalculate Style)

已经生成 DOM 树了,但是 DOM 节点的样式我们依然不知道,要让 DOM 节点拥有正确的样式,这就需要样式计算了。

样式计算的目的是为了计算出 DOM 节点中每个元素的具体样式,这个阶段大体可分为三步来完成。

1. 把 CSS 转换为浏览器能够理解的结构

和 HTML 文件一样,浏览器也是无法直接理解这些纯文本的 CSS 样式,所以当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets

在控制台中输入 document.styleSheets,然后就看到如下图所示的结构:

Image [3].png

渲染引擎会把获取到的 CSS 文本全部转换为 styleSheets 结构中的数据,并且该结构同时具备了查询修改功能,这会为后面的样式操作提供基础。

2. 转换样式表中的属性值,使其标准化

将所有值转换为渲染引擎容易理解的、标准化的计算值,这个过程就是属性值标准化。

Image [4].png

3. 计算出 DOM 树中每个节点的具体样式

样式计算阶段的目的是为了计算出 DOM 节点中每个元素的具体样式,在计算过程中需要遵守 CSS 的继承层叠两个规则。这个阶段最终输出的内容是每个 DOM 节点的样式,并被保存在 ComputedStyle 的结构内

📚CSS 继承

CSS 继承就是每个 DOM 节点都包含有父节点的样式。

📒层叠

层叠是 CSS 的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。它在 CSS 处于核心地位,CSS 的全称“层叠样式表”正是强调了这一点

布局阶段

因为我们还不知道 DOM 元素的几何位置信息。那么接下来就需要计算出 DOM 树中可见元素的几何位置,我们把这个计算过程叫做布局

Chrome 在布局阶段需要完成两个任务:创建布局树布局计算

1. 创建布局树

  • 遍历 DOM 树中的所有可见节点,并把这些节点加到布局树中;
  • 而不可见的节点会被布局树忽略掉,因为它的属性包含 dispaly:none,所以这个元素也没有被包进布局树。

2. 布局计算

当Webkit创建RenderObject对象之后,每个对象是不知道自己的位置,大小等信息的,WebKit根据盒子模型来计算他的位置,大小等信息,这个过程就是布局计算

布局计算是一个复杂的过程,我简单的可以总结为:界面是由很多很多的框模型组成的,每个框模型是由元素的类型以及display属性决定的。而不同的Box会参与到不同的格式上下文中(Formatting Context),完成布局的计算。