了解导航流程——从输入URL戴页面展示,这中间发生了什么

​​​​​​

目录

JS,HTML,CSS如何变成页面的?接下来学习这一渲染过程❤

那么这些子阶段是什么呢?有什么特征?

为什么要构建DOM树?

如何进行样式计算?

什么是布局阶段?怎么布局?

分层是什么?

绘制是干什么的?和生成位图一样吗?

为什么要分块?

绘制完进行栅格化,栅格化是什么?有什么作用?

GPU的作用是什么、

在哪里合成?

我们再来看看三个和渲染流水线相关的概念——“重排”“重绘”和“合成”

重排——更新了元素的几何属性

重绘——更新元素的绘制属性

合成——直接合成阶段


 

从图中可以看出,整个过程需要各个进程之间的配合,回顾下浏览器进程、渲染进程和网络进程的主要职责。

  • 浏览器进程主要负责用户交互、子进程管理和文件储存等功能。
  • 网络进程是面向渲染进程和浏览器进程等提供网络下载功能。
  • 渲染进程的主要职责是把从网络下载的 HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面。因为渲染进程所有的内容都是通过网络获取的,会存在一些恶意代码利用浏览器漏洞对系统进行攻击,所以运行在渲染进程里面的代码是不被信任的。这也是为什么 Chrome 会让渲染进程运行在安全沙箱里,就是为了保证系统的安全。

这个过程可以大致描述为如下。

  1. 首先,浏览器进程接收到用户输入的 URL 请求,浏览器进程便将该 URL 转发给网络进程。
  2. 然后,在网络进程中发起真正的 URL 请求。接着网络进程接收到了响应头数据,便解析响应头数据,并将数据转发给浏览器进程。
  3. 浏览器进程接收到网络进程的响应头数据之后,发送“提交导航 (CommitNavigation)”消息到渲染进程;
  4. 渲染进程接收到“提交导航”的消息之后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道;
  5. 最后渲染进程会向浏览器进程“确认提交”,这是告诉浏览器进程:“已经准备好接受和解析页面数据了”。
  6. 浏览器进程接收到渲染进程“提交文档”的消息之后,便开始移除之前旧的文档,然后更新浏览器进程中的页面状态。

 

JS,HTML,CSS如何变成页面的?接下来学习这一渲染过程❤

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

那么这些子阶段是什么呢?有什么特征?

流水线可分为如下几个子阶段:构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成。

  1. 开始每个子阶段都有其输入的内容;
  2. 然后每个子阶段有其处理过程;
  3. 最终每个子阶段会生成输出内容。

为什么要构建DOM树?

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

如何进行样式计算?

和 HTML 文件一样,浏览器也是无法直接理解这些纯文本的 CSS 样式,所以当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets。(在chrome的控制台输入只需要在控制台中输入 document.styleSheets)

那么接下来就要对其进行属性值的标准化操作。(以需要将所有值转换为渲染引擎容易理解的、标准化的计算值)

接下来就需要计算 DOM 树中每个节点的样式属性了,如何计算呢?

这就涉及到 CSS 的继承规则和层叠规则了。而继承规则就是CSS 继承就是每个 DOM 节点都包含有父节点的样式,层叠是 CSS 的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。MSD

什么是布局阶段?怎么布局?

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

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

创建布局就是我们还要额外地构建一棵只包含可见元素布局树。

分层是什么?

渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree

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

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

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

第二点,需要剪裁(clip)的地方也会被创建为图层。例如了文本内容溢出

绘制是干什么的?和生成位图一样吗?

渲染引擎实现图层的绘制与之类似,会把一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表

绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的。

为什么要分块?

在有些情况下,有的图层可以很大,比如有的页面你使用滚动条要滚动好久才能滚动到底部,但是通过视口,用户只能看到页面的很小一部分,所以在这种情况下,要绘制出所有图层内容的话,就会产生太大的开销,而且也没有必要。

基于这个原因,合成线程会将图层划分为图块(tile),这些图块的大小通常是 256x256 或者 512x512

绘制完进行栅格化,栅格化是什么?有什么作用?

当图层的绘制列表准备好之后,主线程会把该绘制列表提交(commit)给合成线程。合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。

而图块是栅格化执行的最小单位。渲染进程维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行的

GPU的作用是什么、

栅格化过程都会使用 GPU 来加速生成,使用 GPU 生成位图的过程叫快速栅格化,或者 GPU 栅格化,生成的位图被保存在 GPU 内存中。

渲染进程把生成图块的指令发送给 GPU,然后在 GPU 中执行生成图块的位图,并保存在 GPU 的内存中。

在哪里合成?

一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。浏览器进程里面有一个叫 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

合成的图层会被提交给浏览器进程,浏览器进程里会执行显示合成(Display Compositor),也就是将所有的图层合成为可以显示的页面图片。 最终显示器显示的就是浏览器进程中合成的页面图片

我们再来看看三个和渲染流水线相关的概念——“重排”“重绘”和“合成”

这对后续 Web 的性能优化会有很大帮助

重排——更新了元素的几何属性

如果你通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排

重绘——更新元素的绘制属性

如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。

合成——直接合成阶段

那如果你更改一个既不要布局也不要绘制的属性,会发生什么变化呢?渲染引擎将跳过布局和绘制,只执行后续的合成操作,我们把这个过程叫做合成。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值