关于chrome:深入了解现代web浏览器二-导航

25次阅读

共计 3635 个字符,预计需要花费 10 分钟才能阅读完成。

导航栏产生了什么?

这是介绍 Chrome 外部工作博客系列的第 2 局部。在上一篇博客中,咱们学习了不同的过程和线程去解决浏览器的不同局部。在这篇文章,咱们深刻去理解为了展现一个网页每个过程和线程是如何通信的。

咱们看一下 web 浏览器的一个简略示例:当你在浏览器中输出一个 url,浏览器从网络获取数据并且显示一个页面。在本文中,咱们将重点介绍用户申请站点和浏览器筹备渲染一个页面(也称之为导航)。

从浏览器过程开始

正如咱们在第一局部中介绍的 CPU、GPU 和多过程架构,选项卡之外的所有内容都是浏览器过程解决的。浏览器过程具备线程,例如用于绘制按钮和输出局部的 UI 线程,用于解决网络堆栈和从网络获取数据的网络线程,用于管制拜访文件的存储线程。在地址栏中输出 URL,你的输出将由浏览器过程的 UI 线程解决。

简略的导航

步骤 1: 解决输出

当一个用户开始在地址栏中输出内容,UI 线程首先问“这是搜寻还是一个 URL?”。在 Chrome 中,地址栏也是一个搜寻输出区域,因而 UI 线程须要解析并且决定将内容发送给搜索引擎,还是你申请的网站。

步骤 2:开始导航

当用户按下 Enter 键,UI 线程会开始调用网络申请去获取站点内容。在选项卡的角上显示 loading 旋转,网络线程通过相应的协定,例如 DNS 查找,为申请建设 TLS 连贯。


此时,网络线程可能会收到服务器的重定向头比方 http 301。在这种状况下,网络线程与 UI 线程开始通信,服务器申请重定向。而后,会启动另一个 URL 申请。

步骤 3:读取响应

一旦响应体开始回来,网络过程将在必要的时候查看流的前几个字节。响应的 Content-Type 头会阐明是哪种数据类型,然而可能会失落或者谬误,MIME Type 嗅探会在这里实现。就像源码中形容的一样这是一个“辣手的业务”。你能够浏览正文去理解不同浏览器如何解决 content-type/payload 对。

MIME Type 嗅探 MDN 解释:
在缺失 MIME 类型或客户端认为文件设置了谬误的 MIME 类型时,浏览器可能会通过查看资源来进行 MIME 嗅探。每一个浏览器在不同的状况下会执行不同的操作。因为这个操作会有一些平安问题,有的 MIME 类型示意可执行内容而有些是不可执行内容。浏览器能够通过申请头 Content-Type 来设置 X-Content-Type-Options 以阻止 MIME 嗅探。

如果响应是一个 HTML 文件,那么下一步须要将数据传递到渲染过程,然而如果是 zip 文件或者其余文件,则意味着这是一个下载申请,因而须要将数据传递到下载管理器。


也是在这里进行平安浏览查看。如果域名和响应数据与已知的歹意站点匹配,那么网络过程会弹出一个正告去显示一个正告页。此外,Cross Origin Read Blocking(CORB) 触发是为了确保敏感站点数据不传递给渲染过程。

在谷歌的官网是这么解释的:
Cross-Origin Read Blocking (CORB) is an algorithm that can identify and block dubious cross-origin resource loads in web browsers before they reach the web page. CORB reduces the risk of leaking sensitive data by keeping it further from cross-origin web pages. In most browsers, it keeps such data out of untrusted script execution contexts. In browsers with Site Isolation, it can keep such data out of untrusted renderer processes entirely, helping even against side channel attacks like Spectre.

步骤 4:查找渲染过程

当所有的查看都实现,并且网络线程确认导航到申请的站点,网络线程就会告诉 UI 线程数据筹备好了。UI 线程就会查找一个渲染过程负责渲染 web 页面。

因为网络强求须要破费数百毫秒能力失去响应,因而有一个优化用来放慢此过程。当 UI 线程在第 2 步发送一个 URL 申请给网络线程的时候,它一句晓得了须要导航到的站点是哪个。UI 线程被动地尝试查找,并且启动一个与网络申请并行的渲染过程。这样,如果所有合乎预期,当一个网络过程接管到数据的时候,渲染过程曾经处于筹备好的状态。如果导航重定向跨站点那么该筹备好的过程就无奈应用,在这种状况下,可能须要另外一个过程。

步骤 5:提交导航

当初数据和渲染过程都曾经筹备好,从浏览器过程往渲染过程发送一个 IPC 用于提交导航。它也会传递数据流,因而渲染过程能够一直接管 HTML 数据。一旦浏览器过程收到确认提交在渲染过程产生,导航实现并且文档加载阶段开始。

此时,地址栏会更新,平安批示和站点设置 UI 将会反馈出新页面的站点信息。选项卡的会话历史将会 engine,因而“后退 / 后退”按钮将会单步浏览刚刚导航的站点。为了便于复原,你敞开的一个选项卡或者窗口,会话历史会被存储在硬盘上。

额定步骤:初始化记录实现

导航提交后,渲染过程将持续加载资源并且渲染页面。咱们将在下一篇文章中具体介绍在这个阶段产生了什么。当渲染过程“实现”渲染,它会将一个 IPC 发送回浏览器过程(这里是当页面所有 frame 的 onload 事件触发并且执行实现)。此时,UI 过程将进行在选项卡上加载 loading 旋转。

我说的“实现”,因为在此时客户端 Javscript 能够持续加载额定的资源,并且渲染新的视图。

导航到其余站点

简略的导航实现了!然而如果一个用户再次在地址栏输出了另外的 URL 会产生什么?当然,浏览器过程要通过雷同的步骤导航到另外的站点。但在此之前,它须要查看以后渲染的站点,如果它们有 beforeunload 的相干事件。

当你尝试来到或者敞开选项卡的时候, beforeunload 能够创立“来到此站点吗”的正告。选项卡中的所有内容蕴含 Javascript 代码都是渲染过程解决的,因而当一个新的导航申请进来时,浏览器过程必须查看以后的渲染过程。

⚠️ 正告:不要增加无条件的 beforeunload 解决。因为须要在导航前执行处理程序,因为创立了更多的提早。这个事件处理仅仅在须要的时候再去增加,例如须要正告用户可能会失落她们在页面上输出的数据。

如果导航是从渲染过程启动的(例如用户点击了一个链接或者客户端 javascript 运行了 window.location = “https://newsite.com”),渲染过程会首先查看 beforeunload 处理程序。而后,它将会通过与浏览器过程启动导航的雷同步骤。惟一的区别就是导航申请从渲染过程到浏览器过程启动。

当新导航到一个与以后渲染的不同站点时,将会调用一个独立的渲染过程去解决新的导航,以后的渲染过程会持续解决像 unload 之类的事件。更多信息能够查看 页面生命周期转台概述,以及如何应用 页面生命周期 API。

Service Worker 的状况下

这种导航过程的最近更新是引入了 Service Worker。Service Worker 是在你的应用程序中编写网络代理的一种形式;容许 web 开发者更好地管制本地缓存数据和什么时候从网络获取新数据。如果 Service Worker 设置从缓存中读取页面,则无需从网络去申请数据。

须要记住的最重要的局部是 Service Worker 是运行在渲染过程的 Javascript 代码。然而当导航申请进入的时候,然而浏览器过程如何晓得站点是否有 Service Worker?

当一个 Service Worker 注册后,Service Worker 的作用域会保留一个援用(你能够在 Service Worker 生命周期的文章中浏览到更多信息)。当导航开始的时候,网络线程去查看域名是否注册了 Service Worker,如果为一个 url 注册了 Service Worker,UI 过程会查找渲染过程去执行 Service Worker 代码。Service Worker 能够从缓存中加载数据,无需从网络中申请数据,或者也能够从网络中申请新的资源。

导航预加载

如果 Service Worker 最终决定从网络申请数据,那么能够看到在浏览器过程和渲染过程之间的往返会造成提早。导航预加载 是一种通过 Service Worker 启动的同时并行加载资源来放慢这个过程的机制。它应用标记头标记这些申请,使服务器为这些申请发送不同的内容,例如,只更新数据而不是整个文档。

总结

在这篇文章中,咱们学习了导航期间产生了什么,web 应用程序比方响应头和客户端 Javascript 与浏览器是如何交互的。理解浏览器从网络获取数据须要经验的步骤,使得了解为什么开发了例如导航预加载这样的 API。在下一篇文章中,咱们将深入探讨浏览器如何评估咱们的 HTML/CSS/JavaScript 去渲染页面。

正文完
 0