前言
这道经典的面试题能比较全面的考察应试者对 web 应用整体架构的了解,问题涵盖了网络、操作系统、Web应用等一系列的知识,可以说,如果你能回答好这个问题,那么面试基本上成功了一半。
闲话少叙,撸起袖子,我们来一探究竟。
再谈浏览器进程
在正式开讲之前,我们来复习一下浏览器进程的有关知识。我们知道,依据 Chrome 2007 年公布的架构图,浏览器应用内部的结构可以大致分为:
- 浏览器主进程(主要负责界面显示、用户交互、子进程管理,同时提供存储等功能)
- GPU 进程(网页和 Chrome 的 UI 界面的绘制了)
- 网络进程(面向浏览器进程和渲染进程提供资源下载功能)
- 多个渲染进程(核心任务是将 HTML、CSS 和 JS 转化为用户可与之交互的网页)
- 多个插件进程(主要负责插件的运行和管理) 更详细的内容在我的这篇文章中,有兴趣的同学可以戳进去看一下。
主流程
首先,浏览器进程接收到用户输入的 URL 请求后,会将 URL 转发给网络进程,然后在网络进程中发起真正的 HTTP 请求,紧接着,网络进程接收到响应头数据并解析,然后把响应头数据交给浏览器进程,浏览器进程在收到响应头数据之后,会发送一个“提交导航(Commit Navigation)”消息给渲染进程,渲染进程收到“提交导航”消息后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道,最后,渲染进程会向浏览器进程“确认提交”告诉浏览器进程已经做好准备,浏览器在收到渲染进程的“确认提交”后,便会开始删除之前旧的文档,然后更新浏览器进程中的状态。
其中,从发出 HTTP 请求到页面开始解析的过程,叫做“导航”。
详细过程
URL 解析
第一步,地址栏会判断用户输入的是否合法的 URL 地址,如果检测失败,地址栏会把输入内容当作搜索关键字,并使用浏览器默认的搜索引擎将输入内容合成为带搜索关键字的 URL;如果是合法地址,则地址栏会根据规则把这段内容加上协议,合成成为完整的 URL。
URL 请求
第二步,进入页面资源请求过程,这时,浏览器进程会通过 IPC 把 URL 请求发送至网络进程,网络进程在接收到 URL 之后会发起真正的网络请求。网络请求的过程比较复杂,我们一步一步来解释。
首先,网络进程会去查找缓存,如果缓存里面已经存了该资源的副本,并会检查一下保存的过期时间,如果没有过期,就会直接将缓存返回给浏览器进程,如果发现过期了,就会进入网络请求流程。关于浏览器缓存的相关知识在这篇文章里,想要了解的同学戳进去。
网络请求的第一步,先查 DNS 去获取服务器的 IP,在不明确指定端口号的情况下默认使用 80 端口,这些信息都拿到之后,网络进程便会创建 HTTP 请求,然后组装 TCP 头,组装 IP 头,最后先建立 TCP 链接,然后发送 HTTP 请求。详细的 HTTP 请求过程我在这篇文章里已经做过了介绍,想要了解的同学可以戳进去看看。
服务器响应
服务器在接收到请求信息后,会生成相应的响应数据并发送出去。随后,网络进程在接收到响应行和响应头之后,开始解析响应头里的内容。在解析响应头的过程中,如果发现状态码是 301 或者 302,那么就需要进行重定向处理,如果发现状态码是 200,浏览器就会继续处理该请求。通常,对于响应数据,浏览器会有两种处理策略,具体如何处理,会根据响应头里的返回字段 Content-Type 进行区分。如果将响应头里的 Content-Type 配置成了 application/octet-stream,那么浏览器就会将这个请求的类型判断为下载类型,并将它交给浏览器的下载管理器,与此同时,URL 的导航流程完成。但如果是 text/html Html 类型,那么浏览器进程就会通过“提交导航”的方式让渲染进程接手接下来的工作。
渲染进程
默认情况下,Chrome 会为每一个标签页都分配一个渲染进程,但是,在某些极端情况下,也会出现多个页面共用一个渲染进程的情况,当然,这个情况也是形成规则的。
Chrome 的默认策略是,每个标签页对应一个渲染进程,但如果从该页面打开了一个新页面,并且新页面和当前页面属于同一站点,那么这个新页面就会共用父页面的进程。
提交导航
当渲染进程准备好之后,还不能立即进入文档解析状态,因为此时的文档还在网络进程中,那么渲染进程怎么样才能开始干活呢?
当浏览器进程接收到网络进程返回的响应头之后,便会向“提交导航”让渲染进程与网络进程建立通信管道,并开始接收数据渲染页面。
页面渲染
页面渲染的过程十分复杂,我会在后面专门安排一篇文章进行讲解。