likes
comments
collection
share

谷歌官方博客:深入了解现代浏览器系列(其二)

作者站长头像
站长
· 阅读数 18

给前端以福利,给编程以复利。大家好,我是大家的林语冰。

00. 写在前面

在上一篇文章中,我们探讨了不同的进程和线程如何处理浏览器的不同部分。这是探讨 Chrome 内部工作原理的系列博客的第 2 部分,本系列博客一共有四大篇章。 在本文中,我们将深度学习展示网站时,每个进程和线程如何通信。

事实上,这是一道回头率超高的面试题:你在浏览器中输入 URL,然后浏览器从互联网获取数据并显示页面,这个过程发生了什么事?

在这篇文章中,我们来看看谷歌官方博客的标准答案,我们会重点关注用户请求站点和浏览器准备渲染页面的部分,这个过程也称为 导航

免责声明 本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 Inside look at modern web browser (part 2)

01. 导航从浏览器进程开始

谷歌官方博客:深入了解现代浏览器系列(其二)

我们在上一篇博客中科普了 CPU、GPU、内存和多进程架构,选项卡之外的所有内容都由浏览器进程处理。

浏览器进程分为:

  • UI 线程:绘制浏览器的按钮和输入字段
  • 网络线程:处理网络堆栈以从互联网接收数据
  • 存储线程:控制对文件的访问等
  • 其他线程等等

当你在地址栏中输入 URL 时,你的输入将由浏览器进程的 UI 线程处理

02. 一个简单的导航过程

02-1. 第 1 步:处理输入

当用户在地址栏中输入内容时,UI 线程询问的第一件事是“用户输入的是搜索查询,还是 URL?”。

在 Chrome 浏览器中,地址栏也是一个搜索输入字段,因此 UI 线程需要解析,并决定是将你的输出发送到搜索引擎,还是传送到你请求的站点。

谷歌官方博客:深入了解现代浏览器系列(其二)

02-2. 第 2 步:开始导航

当用户按下回车键时,UI 线程会启动网络调用来获取站点内容。

加载旋转器会显示在选项卡的一角,网络线程会执行适当的协议,比如 DNS 查找,并为请求建立 TLS 连接。

谷歌官方博客:深入了解现代浏览器系列(其二)

此时,网络线程可以接收诸如 HTTP 301 之类的服务器重定向标头。

在这种情况下,网络线程与服务器正在请求重定向的 UI 线程进行通信。然后,将发起另一个 URL 请求。

02-3. 第 3 步:读取响应

谷歌官方博客:深入了解现代浏览器系列(其二)

一旦响应主体(有效负载)开始进入,网络线程就会在必要时查看数据流的前几个字节。

响应的 Content-Type 标头应该说明它是什么类型的数据,但由于它可能丢失或错误,因此 MIME 类型嗅探是在此处完成的。

如果响应是 HTML 文件,那么下一步是将数据传递到渲染器进程;但如果它是 zip 文件或其他文件,则意味着它是下载请求,因此它们需要将数据传递到下载管理器。

谷歌官方博客:深入了解现代浏览器系列(其二)

这也是安全浏览检查发生的地方。如果域名和响应数据与已知的恶意站点匹配,那么网络线程会发出警报,显示警告页面。

此外,还会进行跨源读取阻止(CORB)检查,确保敏感的跨站点数据不会进入渲染器进程。

02-4. 第四步:找到渲染进程

一旦完成所有检查,且网络线程确信浏览器应该导航到请求站点,网络线程就会告诉 UI 线程数据已经准备妥当。然后 UI 线程会找到渲染器进程进行网页渲染。

谷歌官方博客:深入了解现代浏览器系列(其二)

由于网络请求可能需要数百毫秒才能得到响应,因此应用了加速此过程的优化。

当 UI 线程在步骤 2 中向网络线程发送 URL 请求时,它已经知道它们要导航到哪个站点。UI 线程会尝试与网络请求并行地主动查找或启动渲染器进程。

这样,如果一切如期进行,那么当网络线程接收到数据时,渲染器进程就已经处于待机位置。如果导航重定向跨站点,那可能不会使用此备用进程,在这种情况下可能需要不同的进程。

02-5. 第 5 步:提交导航

现在数据和渲染器进程已准备就绪,IPC(进程间通信)会从浏览器进程发送到渲染器进程,提交导航。

IPC 还传递数据流,以便渲染器进程可以继续接收 HTML 数据。一旦浏览器进程听到渲染器进程中已发生提交的确认,导航就完成,且文档加载阶段开始。

此时,地址栏已更新,安全指示器和站点设置 UI 反映了新页面的站点信息。该选项卡的会话历史记录将更新,因此后退/前进按钮将逐步浏览刚刚导航到的站点。

为了在关闭选项卡或窗口时方便恢复选项卡/会话,会话历史记录将存储在磁盘上。

谷歌官方博客:深入了解现代浏览器系列(其二)

02-6. 额外步骤:初始加载完成

一旦提交导航,渲染器进程就会继续加载资源,并渲染页面。我们将在下一篇文章中详细介绍此阶段发生的事情。

一旦渲染器进程“完成”渲染,它就会将 IPC 发送回浏览器进程,这发生在页面中的所有帧上触发所有 onload 事件并完成执行之后。

此时,UI 线程会停止选项卡上的加载旋转器。这样,一个简单的导航过程就完成了!

谷歌官方博客:深入了解现代浏览器系列(其二)

03. 导航到不同的站点

但是,如果用户再次在地址栏中输入不同的 URL,又会发生什么呢?

浏览器进程将通过相同的步骤导航到不同的站点。但在此之前,它需要检查当前渲染的站点是否涉及 beforeunload 事件。

当你尝试离开或关闭选项卡时,beforeunload 可以创建“离开此站点?”的警告消息。选项卡内包括 JavaScript 代码的所有内容均由渲染器进程处理,因此当新的导航请求传入时,浏览器进程必须检查当前渲染器进程。

粉丝请注意,请勿滥用 beforeunload 处理程序。它会产生更多延迟,因为处理程序需要在导航开始之前执行。当且仅当需要时添加此事件处理程序,举个栗子,如果需要警告用户可能会丢失在页面上输入的数据。

谷歌官方博客:深入了解现代浏览器系列(其二)

如果导航是从渲染器进程启动的,比如用户单击链接,或者客户端 JavaScript 已运行 window.location = "https://newsite.com",那么渲染器进程首先检查 beforeunload 处理程序。

然后,它会经历与浏览器进程启动导航相同的过程。唯一的区别在于,导航请求是从渲染器进程启动到浏览器进程的。

当新导航指向与当前渲染站点不同的站点时,将调用一个单独的渲染进程来处理新导航,同时保留当前渲染进程来处理诸如 unload 之类的事件。

谷歌官方博客:深入了解现代浏览器系列(其二)

04. Service Worker

导航过程最近的一项变化是引入了 Service Worker。

Service Worker 是一种在应用程序代码中编写网络代理的方法;允许 Web 开发者更好地控制本地缓存的内容,以及何时从网络获取新数据。

如果 Service Worker 设置为从缓存加载页面,则无需从网络请求数据。

粉丝请注意,Service Worker 是在渲染器进程中运行的 JavaScript 代码。但是当导航请求到来时,浏览器进程如何知道该站点有 Service Worker?

谷歌官方博客:深入了解现代浏览器系列(其二)

注册 Service Worker 后,Service Worker 的作用域将保留作为参考。

发生导航时,网络线程会根据注册的 Service Worker 作用域检查域名,如果为该 URL 注册了 Service Worker,那么 UI 线程会找到渲染器进程,执行 Service Worker 代码。

Service Worker 可以从缓存加载数据,而无需从网络请求数据,或者它可以从网络请求新资源。

谷歌官方博客:深入了解现代浏览器系列(其二)

05. 导航预加载

如果 Service Worker 最终决定从网络请求数据,那么浏览器进程和渲染器进程之间的往返可能会导致延迟。

导航预加载是一种通过在 Service Worker 启动时并行加载资源加速此过程的机制。它用标头标记这些请求,允许服务器决定为这些请求发送不同的内容;举个栗子,仅更新数据而不是完整文档。

谷歌官方博客:深入了解现代浏览器系列(其二)

高潮总结

在本文中,我们探讨了导航期间发生的幕后细节,以及响应标头和客户端 JavaScript 等 Web 应用程序代码如何与浏览器交互。

了解浏览器从网络获取数据所经历的步骤,可以更轻松地理解导航预加载等 API 的设计动机。在下一篇博客中,我们将深入探讨浏览器如何执行 HTML/CSS/JavaScript,从而渲染页面。

参考文献

粉丝互动

本期话题是:如何回答:你在浏览器中输入 URL,然后浏览器获取数据并显示页面,这个过程发生了什么事??你可以在本文下方自由言论,文明科普。

欢迎持续关注“前端俱乐部”,给前端以福利,给编程以复利。

坚持阅读的小伙伴可以给自己点赞!谢谢大家的点赞,掰掰~

谷歌官方博客:深入了解现代浏览器系列(其二)

转载自:https://juejin.cn/post/7380296428143460352
评论
请登录