【译】深入了解现代web浏览器(二)-- 导航

原文地址:https://developers.google.com/web/updates/2018/09/inside-browser-part2

导航栏发生了什么?

这是介绍Chrome内部工作博客系列的第2部分。在上一篇博客中,我们学习了不同的进程和线程去处理浏览器的不同部分。在这篇文章,我们深入去了解为了展示一个网页每个进程和线程是如何通信的。

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

从浏览器进程开始

正如我们在第一部分中介绍的CPU、GPU和多进程架构,选项卡之外的所有内容都是浏览器进程处理的。浏览器进程具有线程,例如用于绘制按钮和输入部分的UI线程,用于处理网络堆栈和从网络获取数据的网络线程,用于控制访问文件的存储线程。在地址栏中输入URL,你的输入将由浏览器进程的UI线程处理。

browserprocesses.png
browserprocesses.png

简单的导航

步骤1:处理输入

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

input.png
input.png

步骤2:开始导航

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

navstart.png
navstart.png

此时,网络线程可能会收到服务器的重定向头比如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文件或者其他文件,则意味着这是一个下载请求,因此需要将数据传递到下载管理器。

sniff.png
sniff.png

也是在这里进行安全浏览检查。如果域名和响应数据与已知的恶意站点匹配,那么网络进程会弹出一个警告去显示一个警告页。此外,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页面。


findrenderer.png
findrenderer.png

由于网络强求需要花费数百毫秒才能得到响应,因此有一个优化用来加快此进程。当UI线程在第2步发送一个URL请求给网络线程的时候,它一句知道了需要导航到的站点是哪个。UI线程主动地尝试查找,并且启动一个与网络请求并行的渲染进程。这样,如果一切符合预期,当一个网络进程接收到数据的时候,渲染进程已经处于准备好的状态。如果导航重定向跨站点那么该准备好的进程就无法使用,在这种情况下,可能需要另外一个进程。

步骤5:提交导航

现在数据和渲染进程都已经准备好,从浏览器进程往渲染进程发送一个IPC用于提交导航。它也会传递数据流,因此渲染进程可以不断接收HTML数据。一旦浏览器进程收到确认提交在渲染进程发生,导航完成并且文档加载阶段开始。

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


commit.png
commit.png

额外步骤:初始化记载完成

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

我说的“完成”,因为在此时客户端Javscript可以继续加载额外的资源,并且渲染新的视图。

loaded.png
loaded.png

导航到其他站点

简单的导航完成了!但是如果一个用户再次在地址栏输入了另外的URL会发生什么?当然,浏览器进程要经过相同的步骤导航到另外的站点。但在此之前,它需要检查当前渲染的站点,如果它们有 beforeunload 的相关事件。

当你尝试离开或者关闭选项卡的时候,** beforeunload **可以创建“离开此站点吗”的警告。选项卡中的所有内容包含Javascript代码都是渲染进程处理的,因此当一个新的导航请求进来时,浏览器进程必须检查当前的渲染进程。

⚠️ 警告:不要添加无条件的 **beforeunload **处理。因为需要在导航前执行处理程序,因为创建了更多的延迟。这个事件处理仅仅在需要的时候再去添加,例如需要警告用户可能会丢失她们在页面上输入的数据。


beforeunload.png
beforeunload.png

如果导航是从渲染进程启动的(例如用户点击了一个链接或者客户端javascript运行了 window.location = "https://newsite.com"),渲染进程会首先检查 **beforeunload **处理程序。然后,它将会经过与浏览器进程启动导航的相同步骤。唯一的区别就是导航请求从渲染进程到浏览器进程启动。

当新导航到一个与当前渲染的不同站点时,将会调用一个独立的渲染进程去处理新的导航,当前的渲染进程会继续处理像 **unload **之类的事件。更多信息可以查看 页面生命周期转台概述,以及如何使用 页面生命周期API

unload.png
unload.png

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可以从缓存中加载数据,无需从网络中请求数据,或者也可以从网络中请求新的资源。

serviceworker.png
serviceworker.png

导航预加载

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

navpreload.png
navpreload.png

总结

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容