HTML、CSS和JavaScript,是如何变成页面的?

按照渲染的时间顺序,流水线可分为如下几个子阶段:构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成。

在介绍每个阶段的过程中,应该重点关注以下三点内容:(输入、处理、输出)

1. 开始每个子阶段都有其输入的内容

2. 每个子阶段有其处理过程;

3. 最终每个子阶段会生成输出内容。

(一)构建DOM树

为什么要构建 DOM 树呢?

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

为了更加直观地理解 DOM 树,可以打开 Chrome 的“开发者工具”,选择“Console”标签来打开控制台,然后在控制台里面输入“document”后回车,这样你就能看到一个完整的 DOM 树结构.

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

(二)样式计算

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

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

CSS 样式来源主要有三种:

(1)通过 link 引用的外部 CSS 文件

(2)内联样式

(3)内部样式

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

在控制台中输入 document.styleSheets,然后就看到样式结构

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

属性标准化

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

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

样式计算过程中的第二个规则是样式层叠。层叠是 CSS 的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。

(三)布局阶段

现在,有 DOM 树和 DOM 树中元素的样式,但这还不足以显示页面,因为还不知道 DOM 元素的几何位置信息。

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

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

为了构建布局树,浏览器大体上完成了下面这些工作:

1. 遍历 DOM 树中的所有可见节点,并把这些节点加到布局树中;

2. 不可见的节点会被布局树忽略掉,如 head 标签下面的全部内容,属性包含 dispaly:none,这个元素就没有被包进布局树

如果下载 CSS 文件阻塞了,会阻塞 DOM 树的合成吗?会阻塞页面的显示吗?
不会阻塞DOM 树的合成,但会阻塞页面的显示。
DOM 树和CSSOM树是并行生成的,两个都完成后才进行布局树的生成,但如果期间有JS文件,那就需要等待JS文件加载并执行完成,JS也需要等待CSSOM树生成,因为JS可能操作DOM树和CSSOM树。

(四)分层

页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)。

要想直观地理解什么是图层,可以打开 Chrome 的“开发者工具”,选择“Layers”标签,就可以可视化页面的分层情况,

浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面。

通常情况下,并不是布局树的每个节点都包含一个图层,如果一个节点没有对应的层,那么这个节点就从属于父节点的图层。

那么需要满足什么条件,渲染引擎才会为特定的节点创建新的图层呢?

通常满足下面两点中任意一点的元素就可以被提升为单独的一个图层。

第一点,拥有层叠上下文属性的元素会被提升为单独的一层。

明确定位属性的元素、定义透明属性的元素、使用 CSS 滤镜的元素等,都拥有层叠上下文属性。

第二点,需要剪裁(clip)的地方也会被创建为图层。

(五)图层绘制

在完成图层树的构建之后,渲染引擎会对图层树中的每个图层进行绘制,

(六)栅格化(raster)操作

通常一个页面可能很大,但是用户只能看到其中的一部分,我们把用户可以看到的这个部分叫做视口(viewport)。

合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。(图片懒加载)

(七)合成和显示

总结:

结合上图,一个完整的渲染流程大致可总结为如下:

渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。

渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。

创建布局树,并计算元素的布局信息。

对布局树进行分层,并生成分层树。为每个图层生成绘制列表,并将其提交到合成线程。

合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。

合成线程发送绘制图块命令 DrawQuad 给浏览器进程。

浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值