【经典面试题】从输入URL到WEB 页面完整展示

用户输入

  1. 输入的是关键字:合成新的带搜索关键字的 URL
  2. 输入内容符合 URL 规则,合成为完整的 URL(加上协议如果没有加的话)

URL 请求过程

  1. 浏览器进程会通过进程间通信(IPC)把 URL 请求发送至网络进程
  2. 网络进程会查找本地缓存是否缓存了该资源。如果有缓存资源,那么直接返回资源给浏览器进程(浏览器缓存);
  3. 如果没有,网络进程向web服务器发起http请求(网络请求),请求流程如下:
    5.1 请求前的第一步是要进行 DNS 解析,以获取请求域名的服务器 IP 地址和端口号(DNS域名解析过程)
    5.2 利用 IP 地址和服务器建立 TCP 连接(TCP/IP协议族、HTTP、TCP、TCP/IP四层模型)
    5.3 构建并发送请求头信息
    5.4 服务器返回响应数据,网络进程接收了响应行和响应头之后,就开始解析响应头的内容
  4. 网络进程解析响应流程:
    6.1 检查状态码,如果是 301/302 需要重定向,网络进程会从响应头的 Location 字段里面读取重定向的地址,重新进行第4步。
    6.2 200响应处理:
    检查响应类型Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行
    后续的渲染,如果是html则通知浏览器进程准备渲染进程准备进行渲染。

准备渲染进程

  1. 浏览器进程检查当前url是否和之前打开的渲染进程根域名是否相同(即是否同站 协议+IP),如果相同,则复用原来的进程,如果不同,则开启新的渲染进程

提交文档

  1. 渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息和网络进程建立传输数据的“管道”
  2. 等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程;
  3. 浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态:安全状态、地址栏的 URL、前进后退的历史状态、更新 Web 页面。

-----------到这里,一个完整的导航流程就“走”完了,这之后就要进入渲染阶段了。--------------

渲染阶段

DOM
style
Layout
Layer
Paint
tiles
raster
drawquad
display
  1. 构建 DOM 树:渲染进程将 HTML 转换为浏览器能够理解的DOM 树结构
  2. 样式计算(渲染进程将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式-CSS树):
    2.1 将 CSS 转换为浏览器能够理解的结构styleSheets(document.styleSheets)
    2.2 转换样式表 styleSheets 中的属性值,使其标准化(例如单位、色值表达的统一)
    2.3 计算 DOM 树中每个节点的具体样式(CSS 继承规则和层叠样式)
    2.4 最终输出每个 DOM 节点的样式,并被保存在 ComputedStyle 的结构内
  3. 布局阶段(创建布局树,并计算元素的布局信息):
    3.1 创建布局树,在显示之前需要额外地构建一颗只包含可见元素的布局树
    3.2 布局计算,计算布局树节点的坐标位置
  4. 分层(为特定的节点生成专用的图层,并生成一颗对应的图层树 LayerTree
  5. 图层绘制(为每个图层生成绘制列表,并将其提交到合成线程)
  6. 分块(合成线程将图层分成图块
  7. 栅格化(在光栅化线程池中将图块转换为位图)
  8. 合成(合成线程发送绘制图块命令 DrawQuad 给浏览器进程)
  9. 显示(浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上)

布局树与图层树间的关系

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

那么满足什么条件,渲染引擎会为特定节点创建新的图层呢?通常满足下面任意一点的元素就可以被提升为单独的一个图层:

  1. 拥有层叠上下文属性的元素会被提升为单独的一层
  2. 需要裁减(clip)的地方也会被创建为图层

视觉上经历的三个阶段

从发起 URL 请求开始,到首次显示页面的内容,在视觉上经历的三个阶段。

  • 第一个阶段,等请求发出去之后,到提交数据阶段,这时页面展示出来的还是之前页面的内容
  • 第二个阶段,提交数据之后渲染进程会创建一个空白页面,我们通常把这段时间称为解析白屏,并等待 CSS 文件和 JavaScript 文件的加载完成,生成 CSSOM 和 DOM,然后合成布局树,最后还要经过一系列的步骤准备首次渲染。
  • 第三个阶段,等首次渲染完成之后,就开始进入完整页面的生成阶段了,然后页面会一点点被绘制出来

如何利用分层技术优化代码

需要重点关注的是,合成操作是在合成线程上完成的,这也就意味着在执行合成操作时,是不会影响到主线程执行的。这就是为什么经常主线程卡住了,但是 CSS 动画依然能执行的原因。

利用分层和合成技术来优化代码。在写 Web 应用的时候,你可能经常需要对某个元素做几何形状变换、透明度变换或者一些缩放操作,如果使用 JavaScript 来写这些效果,会牵涉到整个渲染流水线,所以 JavaScript 的绘制效率会非常低下。
这时你可以使用 will-change 来告诉渲染引擎你会对该元素做一些特效变换,CSS 代码如下:

.box {will-change: transform, opacity;}

这段代码就是提前告诉渲染引擎 box 元素将要做几何变换和透明度变换操作,这时候渲染引擎会将该元素单独实现一层,等这些变换发生时,渲染引擎会通过合成线程直接去处理变换,这些变换并没有涉及到主线程,这样就大大提升了渲染的效率。这也是 CSS 动画比 JavaScript 动画高效的原因。
所以,如果涉及到一些可以使用合成线程来处理 CSS 特效或者动画的情况,就尽量使用 will-change 来提前告诉渲染引擎,让它为该元素准备独立的层。
但是凡事都有两面性,每当渲染引擎为一个元素准备一个独立层的时候,它占用的内存也会大大增加,因为从层树开始,后续每个阶段都会多一个层结构,这些都需要额外的内存,所以你需要恰当地使用 will-change。

什么情况下会创建图层

  1. HTML 根元素
  2. position 不是 static 并且设置了 z-index 属性
  3. 设置透明度 opacity 非 1
  4. 设置 filter 非 none
  5. 设置 transform 非 none
  6. 设置 will-change

参考文献

带你看看从输入URL到页面显示背后的故事

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值