04 导航流程:从输入url到打开页面发生了什么

Posted by CodingWithAlice on April 8, 2021

04 导航流程:从输入url到打开页面发生了什么

看到一篇还不错的更底层的讲解博客:从 URL 输入到页面展现到底发生了什么?

导航流程:用户发出URL请求到页面开始解析的这个过程

从输入URL到页面展示流程:

image-20210408215608834

1、用户输入

浏览器进程中的 UI 线程 对输入内容做区分,并生成对应 URL

  • 如果查询关键字是 url – 根据规则,把这段内容加上协议,合成为完整的 URL
  • 如果查询关键字是 搜索内容 – 使用浏览器默认的搜索引擎,来合成新的带搜索关键字的 URL ## 2、URL请求过程 浏览器进程 - UI 线程 会通过进程间通信(IPC)把 URL 请求发送至网络进程 — > 此时浏览器标签页的标题会出现 “加载中” 的图标

URL请求流程:

1、网络进程 会查找 本地缓存 是否缓存了该资源

  • 有,直接返回资源
  • 没有缓存,进入网络请求流程

2、第一步是要进行 DNS解析,获取 ip 地址

  • 如果请求协议是HTTPS,那么还需要建立 TLS 连接

3、利用IP地址和服务器建立 TCP连接

4、浏览器端会构建请求行、请求头等信息,并把和 该域名相关Cookie 等数据附加到请求头中,然后 向服务器发送构建好的请求信息

5、服务器会根据请求信息 生成响应数据,并发给 网络进程

7、网络进程会解析响应头

  • 返回的状态码是 301 或者 302 – 重定向,网络进程 会从响应头的 Location 字段里面读取重定向的地址 —> 网络进程会通知 UI线程 需要重定向 —> 然后以新的地址开始请求资源,一切又重头开始了
  • 状态码是200,继续解析

8、对响应数据类型处理,网络进程 通过响应头中的 Content-Type 区分响应体中的数据类型

  • 如果属性值为text/html - HTML格式,继续进行导航流程,浏览器进程需要 准备渲染进程

  • 如果属性值为 application/octet-stream - 字节流类型 –> 通常情况下,浏览器会按照下载类型来处理该请求 —> 该请求会被提交给浏览器的下载管理器,同时该URL请求的 导航流程就此结束

    image-20210408220356655

    3、准备渲染进程

    渲染进程策略:

  • 默认情况下,Chrome 会为 每个页面分配一个渲染进程
  • 新页面和当前页面属于同一站点,那么新页面会复用父页面的渲染进程 –> 多个页面直接运行在同一个渲染进程 中【process-per-site-instance策略】

注意:同一站点(same-site)要求 —> 根域名(例如,geekbang.org)加上协议(例如,https:// 或者http://),还包含了该根域名下的所有子域名和不同的端口,如下所示:

https://time.geekbang.org
https://www.geekbang.org
https://www.geekbang.org:8080

注意:浏览器进程把渲染进程准备好之后,还不能立即进入文档解析状态,因为此时的文档数据还在 网络进程 中,并没有提交给渲染进程,所以下一步就进入了提交文档阶段

4、提交文档

文档:指URL请求的响应体数据 准备好渲染进程之后,在三个进程之间有个“提交文档”的消息在处理,处理流程如下:

image-20210408220519097

1⃣️:浏览器进程渲染进程 发出“提交文档”的消息 2⃣️:渲染进程接 收到“提交文档”的消息后,会和 网络进程 建立传输数据的“管道”,边传边解析 3⃣️:等文档数据传输完成之后,渲染进程 会返回“确认提交”的消息给 浏览器进程 4⃣️:浏览器进程 在收到“确认提交”的消息后,会更新浏览器界面状态,包括了 安全状态、地址栏的URL、前进后退的历史状态(硬盘内存),并更新Web页面,即下图标注的四个内容

image-20210408221028061

所以:在浏览器的地址栏里面输入了一个地址后,之前的页面没有立马消失,而是要加载一会儿才会更新页面

5、渲染阶段

在这个阶段进行页面解析和子资源(iframe)加载,完成后 渲染进程 会发送一个消息给 浏览器进程 —> 也就是 onLoad 事件触发后发送 —>浏览器接收到消息后,UI线程会停止标签图标上的加载动画

image-20210408221050867

但这里”结束”并不意味着所有的加载工作都结束了,因为可能还有 JavaScript 在加载额外的资源或者渲染新的视图。

6、访问不同的站点

1-5 是一次完整的普通访问,当我们输入另外的地址时,浏览器会重复上面的过程。

但是 在开始新的访问前,会确认当前的站点是否关心 beforeunload 事件。由于所有的包括渲染、运行 Javascript 的工作都发生在渲染进程中,浏览器进程需要在 新的访问开始前 与渲染进程确认当前的站点是否关心unload

  • 补充:

    beforeunload事件可以提醒用户 是否要访问新的站点或者关闭页签,如果用户拒绝则新的访问或关闭会被阻止。

  • 案例:

    如果一次访问是从一个渲染进程中发起的,例如用户点击一个链接或者运行 JavaScript 代码location = 'http://newsite.com'时,渲染进程首先检查beforeunload

    然后再执行和浏览器进程初始化访问同样的步骤,只不过区别在于这样的访问请求是 由渲染进程向浏览器进程发起的