浏览器运行原理(二)

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战web

输入搜索内容的过程发生了什么?

也许大多数人使用 Chrome 最多的场景就是在地址栏输入关键字进行搜索或者输入地址导航到某个网站,咱们来看看浏览器是怎么看待这个过程的。api

咱们知道浏览器 Tab 外的工做主要由 Browser Process 掌控,Browser Process(Browser进程) 又对这些工做进一步划分,使用不一样线程进行处理:浏览器

  • UI thread (UI线程): 控制浏览器上的按钮及输入框;
  • network thread(netWork线程): 处理网络请求,从网上获取数据;
  • storage thread(storage线程): 控制文件等的访问;

image.png 回到咱们的问题,当咱们在浏览器地址栏中输入文字,并点击回车得到页面内容的过程在浏览器看来能够分为如下几步:缓存

  1. 处理输入

UI thread 须要判断用户输入的是 URL 仍是 query;服务器

  1. 开始导航

当用户点击回车键,UI thread 通知 network thread 获取网页内容,并控制 tab 上的 spinner 展示,表示正在加载中。markdown

network thread 会执行 DNS 查询,随后为请求创建 TLS 链接网络

image.png 若是 network thread 接收到了重定向请求头如 301,network thread 会通知 UI thread 服务器要求重定向,以后,另一个 URL 请求会被触发。oop

3. 读取响应post

当请求响应返回的时候,network thread 会依据 Content-Type 及 MIME Type sniffing 判断响应内容的格式网站

image.png 判断响应内容的格式

若是响应内容的格式是 HTML ,下一步将会把这些数据传递给 renderer process,若是是 zip 文件或者其它文件,会把相关数据传输给下载管理器。

Safe Browsing 检查也会在此时触发,若是域名或者请求内容匹配到已知的恶意站点,network thread 会展现一个警告页。此外 CORB 检测也会触发确保敏感数据不会被传递给渲染进程。

image.png

4. 查找渲染进程

当上述全部检查完成,network thread 确信浏览器能够导航到请求网页,network thread 会通知 UI thread 数据已经准备好,UI thread 会查找到一个 renderer process 进行网页的渲染。

image.png 收到 Network thread 返回的数据后,UI thread 查找相关的渲染进程

因为网络请求获取响应须要时间,这里其实还存在着一个加速方案。当 UI thread 发送 URL 请求给 network thread 时,浏览器其实已经知道了将要导航到那个站点。UI thread 会并行的预先查找和启动一个渲染进程,若是一切正常,当 network thread 接收到数据时,渲染进程已经准备就绪了,可是若是遇到重定向,准备好的渲染进程也许就不可用了,这时候就须要重启一个新的渲染进程。

5. 确认导航

进过了上述过程,数据以及渲染进程均可用了, Browser Process 会给 renderer process 发送 IPC 消息来确认导航,一旦 Browser Process 收到 renderer process 的渲染确认消息,导航过程结束,页面加载过程开始。

此时,地址栏会更新,展现出新页面的网页信息。history tab 会更新,可经过返回键返回导航来的页面,为了让关闭 tab 或者窗口后便于恢复,这些信息会存放在硬盘中。

image.png Browser Process 和 Renderer Process 经过 IPC 通讯,请求 Renderer Process 渲染页面

6. 额外的步骤

一旦导航被确认,renderer process 会使用相关的资源渲染页面,下文中咱们将重点介绍渲染流程。当 renderer process 渲染结束(渲染结束意味着该页面内的全部的页面,包括全部 iframe 都触发了 onload 时),会发送 IPC 信号到 Browser process, UI thread 会中止展现 tab 中的 spinner。

image.png Renderer Process 发送 IPC 消息通知 browser process 页面已经加载完成

固然上面的流程只是网页首帧渲染完成,在此以后,客户端依旧可下载额外的资源渲染出新的视图。

在这里咱们能够明确一点,全部的 JS 代码其实都由 renderer Process 控制的,因此在你浏览网页内容的过程大部分时候不会涉及到其它的进程。不过也许你也曾经监听过 beforeunload 事件,这个事件再次涉及到 Browser Process 和 renderer Process 的交互,当当前页面关闭时(关闭 Tab ,刷新等等),Browser Process 须要通知 renderer Process 进行相关的检查,对相关事件进行处理。

image.png 浏览器进程发送 IPC 消息给渲染进程,通知要离开当前网站了

若是导航由 renderer process 触发(好比在用户点击某连接,或者JS执行 window.location = "[http://newsite.com](https://link.zhihu.com/?target=http%3A//newsite.com/)" ) renderer process 会首先检查是否有 beforeunload 事件处理器,导航请求由 renderer process 传递给 Browser process

若是导航到新的网站,会启用一个新的 render process 来处理新页面的渲染,老的进程会留下来处理相似 unload 等事件。

关于页面的生命周期,更多内容可参考 Page Lifecycle API 。

image.png 浏览器进程发送 IPC 消息到新的渲染进程通知渲染新的页面,同时通知旧的渲染进程卸载

除了上述流程,有些页面还拥有 Service Worker (服务工做线程),Service Worker 让开发者对本地缓存及判断什么时候从网络上获取信息有了更多的控制权,若是 Service Worker 被设置为从本地 cache 中加载数据,那么就没有必要从网上获取更多数据了。

值得注意的是 service worker 也是运行在渲染进程中的 JS 代码,所以对于拥有 Service Worker 的页面,上述流程有些许的不一样。

当有 Service Worker 被注册时,其做用域会被保存,当有导航时,network thread 会在注册过的 Service Worker 的做用域中检查相关域名,若是存在对应的 Service worker,UI thread 会找到一个 renderer process 来处理相关代码,Service Worker 可能会从 cache 中加载数据,从而终止对网络的请求,也可能从网上请求新的数据。

image.png Service Worker 依据具体情形作处理

关于 Service Worker 的更多内容可参考 The Service Worker Lifecycle

若是 Service Worker 最终决定经过网上获取数据,Browser 进程 和 renderer 进程的交互其实会延后数据的请求时间 。Navigation Preload 是一种与 Service Worker 并行的加速加载资源的机制,服务端经过请求头能够识别这类请求,而作出相应的处理。

相关文章
相关标签/搜索