那么今天我们就一起来探索下这个流程,下图是我梳理出的“从输入 URL 到页面展示完整流程示意图”:
从图中可以看出,整个过程需要各个进程之间的配合,所以在开始正式流程之前,
我们还是先来快速回顾下浏览器进程、渲染进程和网络进程的主要职责。
浏览器进程主要负责用户交互、子进程管理和文件储存等功能。
网络进程是面向渲染进程和浏览器进程等提供网络下载功能。
渲染进程的主要职责是把从网络下载的 HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面。因为渲染进程所有的内容都是通过网络获取的,会存在一些恶意代码利用浏览器漏洞对系统进行攻击,所以运行在渲染进程里面的代码是不被信任的。这也是为什么 Chrome 会让渲染进程运行在安全沙箱里,就是为了保证系统的安全。
加入浏览器进程的,载入url流程:
1,用户输入url并回车
2,浏览器进程检查url,组装协议,构成完整的url
3,浏览器进程通过进程间通信(IPC)把url请求发送给网络进程
4,网络进程接收到url请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程
5,如果没有,网络进程向web服务器发起http请求(网络请求),请求流程如下:
5.1 进行DNS解析,获取服务器ip地址,端口(端口是通过dns解析获取的吗?这里有个疑问)
5.2 利用ip地址和服务器建立tcp连接
5.3 构建请求头信息
5.4 发送请求头信息
5.5 服务器响应后,网络进程接收响应头和响应信息,并解析响应内容
6,网络进程解析响应流程;
6.1 检查状态码,如果是301/302,则需要重定向,从Location自动中读取地址,重新进行第4步
(301/302跳转也会读取本地缓存吗?这里有个疑问),如果是200,则继续处理请求。
6.2 200响应处理:
检查响应类型Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行
后续的渲染,如果是html则通知浏览器进程准备渲染进程准备进行渲染。
7,准备渲染进程
7.1 浏览器进程检查当前url是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程
8. 传输数据、更新状态
8.1 渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息和网络进程建立传输数据的“管道”
8.2 渲染进程接收完数据后,向浏览器发送“确认提交”
8.3 浏览器进程接收到确认消息后更新浏览器界面状态:安全、地址栏url、前进后退的历史状态、更新web页面。
- 那什么情况下多个页面会同时运行在一个渲染进程中呢?
要解决这个问题,我们就需要先了解下什么是同一站点(same-site)。具体地讲,我们将“同一站点”定义为根域名(例如,geekbang.org)加上协议(例如,https:// 或者 http://),还包含了该根域名下的所有子域名和不同的端口,比如下面这三个:https://time.geekbang.org
https://www.geekbang.org
https://www.geekbang.org:8080
它们都是属于同一站点,因为它们的协议都是 HTTPS,而且根域名也都是 geekbang.org。Chrome 的默认策略是,每个标签对应一个渲染进程。但如果从一个页面打开了另一个新页面,而新页面和当前页面属于同一站点的话,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫 process-per-site-instance。
总结来说,打开一个新页面采用的渲染进程策略就是:通常情况下,打开新的页面都会使用单独的渲染进程;如果从 A 页面打开 B 页面,且 A 和 B 都属于同一站点的话,那么 B 页面复用 A 页面的渲染进程;如果是其他情况,浏览器进程则会为 B 创建一个新的渲染进程。渲染进程准备好之后,还不能立即进入文档解析状态,因为此时的文档数据还在网络进程中,并没有提交给渲染进程,所以下一步就进入了提交文档阶段。