在导航过程中会发生什么
该博客系列共包含 4 部分,专门介绍 Chrome 的内部工作原理,这是第 2 部分。 在上一篇博文中,我们介绍了 进程和线程负责处理浏览器的不同部分在这篇博文中,我们将深入探讨 每个进程和线程都会通信,以便显示网站。
我们来看一个简单的网络浏览用例:您在浏览器中键入网址,然后在浏览器中 从互联网提取数据并显示网页。在这篇博文中,我们将重点介绍 当用户请求访问网站时,浏览器就准备呈现网页(也称为导航)。
首先是浏览器进程
![浏览器进程](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/browser-processes-1abcf214c73ef.png?authuser=8&hl=cs)
我们在本课程中 第 1 部分:CPU、GPU、内存和多进程架构, 标签页以外的所有内容都由浏览器进程处理。 浏览器进程具有类似于界面线程的线程,用于绘制 浏览器(处理网络堆栈以从互联网接收数据的网络线程), 控制文件访问等的存储线程。当您在地址中输入网址时 则表示您的输入由浏览器进程的界面线程处理。
简单的导航
第 1 步:处理输入
当用户开始在地址栏中输入内容时,界面线程首先会询问:“这是 搜索查询或网址?”。在 Chrome 中,地址栏也是一个搜索输入字段 需要解析并决定是将您转到搜索引擎还是您请求的网站。
![处理用户输入](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/handling-user-input-24fea2c817a6a.png?authuser=8&hl=cs)
第 2 步:开始导航
当用户点击进入按钮时,界面线程会发起网络调用以获取网站内容。加载旋转图标 显示在标签页的一角,且网络线程会经过相应的协议,例如 为请求进行 DNS 查找并建立 TLS 连接。
![导航开始](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/navigation-start-4aeb163d61a8c.png?authuser=8&hl=cs)
此时,网络线程可能会收到服务器重定向标头,如 HTTP 301。在这种情况下 网络线程与服务器请求重定向的界面线程进行通信。然后, 系统会发起另一个网址请求
第 3 步:阅读回答
![HTTP 响应](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/http-response-0ae2751b24973.png?authuser=8&hl=cs)
一旦响应正文(载荷)开始进入,网络线程会查看前几个字节 (如有必要)。响应的 Content-Type 标头应指明数据类型 但由于它可能有缺失或错误 MIME 类型嗅探 这里就完成了这是一项“棘手的业务”如源代码中所注释的那样。 您可以阅读该注释,了解不同的浏览器如何处理“内容类型/载荷”对。
如果响应是一个 HTML 文件,那么下一步是将数据传递给渲染程序 但如果是 zip 文件或其他文件,则表示它是一个下载请求, 他们需要将数据传递给内容下载管理器。
![MIME 类型嗅探](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/mime-type-sniffing-444e1a2f5b037.png?authuser=8&hl=cs)
这也是SafeBrowsing检查的地方。 如果域名和响应数据似乎与某个已知的恶意网站匹配,那么此网络线程 显示警告页面。此外, Ross Origin Read Blocking (CORB) 以便确保跨网站 数据不会进入渲染器进程。
第 4 步:查找渲染程序进程
完成所有检查且网络线程确信浏览器应导航到 请求的网站,网络线程会通知界面线程数据已就绪。然后,界面线程会 渲染程序进程继续渲染网页
![查找渲染程序进程](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/find-renderer-process-4d4055665d4a7.png?authuser=8&hl=cs)
由于网络请求可能需要几百毫秒才能获取响应, 以加快此过程。当界面线程向 网络线程,那么它已经知道用户要导航到哪个网站。界面线程 尝试主动查找或启动与网络请求并行的渲染器进程。这样, 如果一切按预期进行,那么在网络线程 收到的数据。如果导航在跨网站重定向中, 在这种情况下,可能需要执行不同的流程。
第 5 步:提交导航
现在,数据和渲染程序进程都已准备就绪,浏览器进程向 渲染程序进程提交导航。它还会传递数据流 进程可以持续接收 HTML 数据。当浏览器进程听到确认已提交 发生在渲染器进程中,导航已完成,且文档加载阶段 。
此时,地址栏会更新,安全指示器和网站设置界面会反映 新网页的网站信息。该标签页的会话历史记录会进行更新,以便往返 按钮可以分步浏览刚刚浏览的网站。便于恢复标签页/会话 当您关闭标签页或窗口时,会话记录会存储在磁盘中。
![提交导航](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/commit-navigation-bc2943921c6f6.png?authuser=8&hl=cs)
额外步骤:初始加载完成
提交导航后,渲染器进程会加载资源,
页面。我们将在下一篇帖子中详细介绍此阶段会发生什么。渲染程序
进程“完成”它会将 IPC 发送回浏览器进程(完成所有
onload
事件已针对页面中的所有帧触发并执行完毕)。此时,
界面线程会停止标签页上的“正在加载”旋转图标。
我说“finishes”,因为客户端 JavaScript 仍然可以加载 并在此后渲染新的视图。
![页面完成加载](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/page-finish-loading-1bee6888e9e56.png?authuser=8&hl=cs)
导航到其他网站
简单的导航已完成!但是,如果用户在地址栏中输入不同的网址,会出现什么情况
吗?浏览器进程要执行相同的步骤才能导航到不同的网站。
但在此之前,它需要确认当前呈现的网站是否关心
beforeunload
事件。
beforeunload
可以创建“要离开此网站吗?”在您尝试离开或关闭标签页时发送提醒。
标签页内的所有内容(包括 JavaScript 代码)均由渲染器进程处理,因此
收到新导航请求时,浏览器进程必须与当前的渲染程序进程进行检查。
![beforeunload 事件处理脚本](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/beforeunload-event-handle-53b6fa7dd9be3.png?authuser=8&hl=cs)
如果导航是从渲染程序进程发起的(例如用户点击链接或
客户端 JavaScript 已运行 window.location = "https://newsite.com"
)渲染器进程
首先检查 beforeunload
处理程序。然后,它会通过与浏览器进程相同的进程
启动导航。唯一的区别在于,导航请求是从
渲染程序进程传递到浏览器进程
当新的导航指向与当前呈现的网站不同的网站时,单独的呈现
系统会调用进程来处理新的导航,同时将当前渲染进程保留在
处理 unload
等事件。如需了解详情,请参阅页面生命周期状态概览
以及如何借助
Page Lifecycle API。
![新的导航并卸载](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/new-navigation-unload-29ee714c3fcf4.png?authuser=8&hl=cs)
对于 Service Worker
此导航流程最近的一项更改是引入了 Service Worker。Service Worker 是一种 网络代理让网站开发者能够更好地控制 本地缓存以及何时从网络获取新数据。如果 Service Worker 设置为加载页面 因此无需从网络请求数据。
需要注意的重要一点是,Service Worker 是在渲染程序中运行的 JavaScript 代码。 过程。但是,当导航请求传入时,浏览器进程如何知道网站已有 Service Worker?
![Service Worker 范围查询](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/service-worker-scope-look-f48a8d509535a.png?authuser=8&hl=cs)
注册 Service Worker 时,Service Worker 的作用域将作为引用保留 (如需详细了解范围,请参阅 Service Worker 生命周期一文)。 发生导航时,网络线程会根据已注册的 Service Worker 检查网域 作用域,如果针对该网址注册了 Service Worker,则界面线程会在 来执行 Service Worker 代码Service Worker 可从缓存加载数据, 需要从网络请求数据,或者可能会从网络请求新资源。
![Service Worker 导航](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/serviceworker-navigation-8576df1bffcf9.png?authuser=8&hl=cs)
导航预加载
您可以看到,浏览器进程与渲染程序进程之间的这种往返可能会导致延迟 如果 Service Worker 最终决定从网络请求数据。 Navigation Preload 是加快加载过程的 在 Service Worker 的启动过程中并行加载资源。 它会使用标头标记这些请求,以便服务器决定为哪些请求发送不同的内容 这类请求;例如,只更新数据,而不是整个文档。
![Navigation 预加载](https://developer.chrome.google.cn/static/blog/inside-browser-part2/image/navigation-preload-a859b1ad065e3.png?authuser=8&hl=cs)
小结
在这篇博文中,我们了解了导航期间会发生什么,以及您的 Web 应用代码是如何 响应标头和客户端 JavaScript 与浏览器交互。了解浏览器的步骤 以便从网络获取数据,从而更轻松地理解导航等 API 开发了预加载功能。在下一篇博文中,我们将深入介绍浏览器 HTML/CSS/JavaScript 来呈现网页。
您喜欢这个帖子吗?如果您对以后的帖子有任何疑问或建议, 通过下方的评论部分或 Twitter 上的 @kosamari 分享自己的想法。