探索现代浏览器(二)|在导航栏里输入并按下回车会发生什么? 您所在的位置:网站首页 49浏览器导航 探索现代浏览器(二)|在导航栏里输入并按下回车会发生什么?

探索现代浏览器(二)|在导航栏里输入并按下回车会发生什么?

2024-02-19 02:51| 来源: 网络整理| 查看: 265

Hi 大家好,这里是 探索现代浏览器 专栏的第二篇,今天我们来一起探索一个经典的前端问题:

当我们在浏览器导航栏里输入一个 URL 并按下回车,都会发生什么?

看到这道题目,很多前端开发者会立马想起一些刻在肌肉记忆里的答案:

DNS 查询 TCP 连接 处理请求 接受响应 渲染页面 ……

那么这些答案对吗?

对,但又不对

说对,是因为上面列的答案的确是输入 URL 并按下回车后会发生的事情;

说不对,是因为上面的列的答案太过于笼统,没明确说明每个流程到底是什么。

而且大家有没有细想过把 DNS查询 放在第一步的逻辑依据到底是什么?如果真要说第一步发生了什么,那恐怕要追溯到键盘输入到系统交互等等了。

当然了,在这里我也知识抛砖引玉,这篇文章是我见过对这个问题最完整的总结。

今天在这里真正想跟大家探索的是浏览器导航(navigation)的过程:也就是网站数据请求以及浏览器在呈现网页之前做的准备工作。

浏览器中一个最简单的导航(Navigation)过程 Step1 处理输入

浏览器进程中有 UI 线程,当你在导航栏里面输入一个 URL 的时候,其实就是 UI线程(UI thread) 在处理你的输入。

当用户开始在导航栏上面输入内容的时候,UI线程做的第一件事就是询问: 你输入的字符串是一些搜索的关键词还是一个URL地址呢?

用户在导航栏输入信息的时候 UI线程 要进行一系列的解析来判定是将用户输入发送给搜索引擎还是直接请求你输入的站点资源。

image.png

你是要访问 baidu.com,还是要搜索 baidu.com?

image.png

Step2 开始导航

当用户按下回车键的时候,UI线程 会叫 网络线程(network thread) 初始化一个网络请求来获取站点的内容。

这时候 tab 上会展示一个提示资源正在加载中的旋转圈圈,而且网络线程会进行一系列诸如 DNS 寻址以及为请求建立 TLS 连接的操作。

如果网络线程收到服务器的HTTP 301重定向响应,它就会告知UI线程进行重定向然后它会再次发起一个新的网络请求。

image.png

Step3 读取响应

网络线程在接收到 HTTP 响应体后:

通过 HTTP 头部的 Content-Type 来确定响应体的 MIME 类型 如果是文件类型(比如 zip),那么会交给下载管理器去处理 如果是一个 HTML 文件,浏览器会将响应数据交给 渲染进程(renderer process) 去做下一步工作。在把内容交给渲染进程之前还会对内容做安全检查。如果请求的域名或者响应的内容和某个已知的病毒网站相匹配,网络线程会给用户展示一个警告的页面。

从 Content-Type 中确定类型:

image.png

进行安全检查:

image.png

Step4 寻找渲染进程

网络线程处理完之后会通知 UI 线程,UI 线程 在收到网络线程的确认后就会为这个网站寻找一个 渲染进程 来渲染页面。

由于网络请求耗时可能会很久,所以浏览器会做一些优化:

在 Step2 中 当UI线程发送URL链接给网络线程后,它其实已经知晓它们要被导航到哪个站点了,所以在网络线程干活的时候,UI线程 会主动地为这个网络请求启动一个 渲染进程。这样就节省了创建渲染进程的时间。

image.png

Step5 提交导航

浏览器进程 会通过 IPC 告诉 渲染进程 去提交本次导航(commit navigation)。

同时 浏览器进程 还会将刚刚接收到的响应数据流传递给对应的 渲染进程 去处理。

一旦 浏览器进程 收到 渲染线程 的回复说导航已经被提交了(commit),整个导航过程就结束了。

此时,导航栏会被更新,安全指示符(url 前的小图标)和站点设置UI会展示新页面相关的站点信息。当前tab的会话历史(session history)也会被更新。这样当你点击浏览器的前进和后退按钮也可以导航到刚刚导航完的页面。

image.png

Step6 完成初始化加载

当导航提交完成后,渲染进程就会开始加载资源和渲染画面。

当页面上所有帧(frames)的 onload 事件都已经被触发了而且执行完成的时候,渲染进程 会通过 IPC 通知 浏览器进程,然后 UI线程 就会停止导航栏上的 loading。

image.png

导航至另一个站点

前面讲的是一个最简单的导航场景。如果用户是从 a 页面导航到了 b 页面,会发生什么呢?

在浏览器导航栏里输入

第一种场景是在导航栏里输入 b 页面的 URL。

浏览器进程会重新执行一遍之前的那几个步骤来完成新站点的导航。

不过在浏览器进程做这些事情之前,它需要让当前的渲染页面做一些收尾工作,具体就是询问一下当前的渲染进程需不需要处理一下 beforeunload 事件。

开发者可以在这个事件中添加一些离开页面的二次确认弹窗。

不过要注意的是,不要随便给页面添加 beforeunload 事件监听,你定义的监听函数会在页面被重新导航的时候执行,因此这会增加重导航的时延。beforeunload 事件监听函数只有在十分必要的时候才能被添加。

image.png

在当前站点页面内发起

如果是在页面内发起的导航到另一个站点(比如 window.location = 'b.com'),这种情况下,渲染进程会自己先检查一个它有没有注册 beforeunload 事件的监听函数,如果有的话就执行,执行完后发生的事情就和之前的情况没什么区别了。

唯一的不同就是这次的导航请求是由渲染进程给浏览器进程发起的。 同时会有另外一个渲染进程被启动来完成这次重导航,而当前的渲染进程会继续处理现在页面的一些收尾工作,例如 unload 事件的监听函数执行。

image.png

特殊的导航场景 — Service Worker

Service Worker 是跑在 渲染进程 里的。

它主要可以用于让开发者可以更灵活的控制网络请求,例如决定哪些数据要走缓存,哪些要重新走网络请求等等。如果开发者在service worker里设置了当前的页面内容从缓存里面获取,当前页面的渲染就不需要重新发送网络请求了,这就大大加快了整个导航的过程。

Service Worker 在注册时需要提供 scope。在导航开始的时候,网络线程会根据请求的域名在已经注册的 Service Worker 作用范围里面寻找有没有对应的 Service Worker。如果有命中该 URL 的 Service Worker,UI线程 就会为这个 Service Worker 启动一个渲染进程 来执行它的代码。

网络线程检查是否有注册 Service Worker

image.png

启动一个渲染进程,运行 Service Worker

image.png

(关于更多 Service Worker 的介绍,大家也可以移步我的另一篇文章)

写在最后

标题提到的这道经典题目涉及到的知识体系非常之广,今天呢也只是跟大家一起探索了其中关于导航的部分。其他部分比如渲染 相关的会在后面的章节再和大家一起探索~

不知道关于导航这部分大家有没有其他补充的呢?欢迎在评论区里一起交流~

参考文章

Inside look at modern web browser (part 2)

www.dailichun.com/2018/03/12/…



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有