1. Chrome
1. 浏览器总体
Chrome 进程架构
从图中可以看出,最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。
-
浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
-
渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
- JavaScript 引擎线程:V8 引擎
- 定时触发器线程:setTimeout,setInterval。计数完毕后,将事件加入任务队列的尾部,等待 JS 引擎线程执行。
- 事件触发线程:回调。将准备好的事件交给 JS 引擎线程执行。
- 异步 http 请求线程:负责执行异步请求一类的函数的线程,如:Promise,axios,ajax 等。
-
GPU 进程。其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
-
网络进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
-
插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。
渲染进程 + 内部线程
- 主线程(js 引擎线程)
- GUI 渲染线程
- 事件触发线程
- 定时器触发线程
- http 请求线程
一、主线程
主线程 主要用于处理 js 代码(解析、执行)。只要消息队列不为空,就会一直从中取任务执行。由于主线程和 GUI 线程的互斥,所以当一个 js 任务执行过长时,会阻塞页面的渲染,造成页面的卡顿。
二、GUI 渲染线程
GUI 渲染线程 负责解析 HTML、CSS、合成 CSSOM 树、布局树、绘制、分层、栅格化、合成。重绘、重排、合成都在该线程中执行。
- GUI 线程和 JS 引擎线程是冲突的,当 GUI 线程执行时,js 引擎线程会被挂起;当 js 引擎线程执行任务时,有需要 GUI 线程执行的任务,会被保存到一个队列中,等待 js 引擎执行完执行。
三、事件触发线程
当 js 代码在解析时,遇到事件时,比如鼠标监听,会将这些任务添加到事件触发线程中。等事件触发时,会将任务从事件触发线程中取出,放到消息队列的队尾等待执行。
四、定时器触发线程
用于存放 setTimeout、setInterval 等任务,在解析遇到这些任务时,js 引擎会将这些任务放到定时器触发线程中,并开始计 数,时间到了之后,将任务放到消息队列中等待执行。
五、http 请求线程
用于检测 XMLHttpRequest 请求,当请求状态改变时,将设置的回调函数添加到消息队列中等待执行。
1个页面有几个进程
打开 1 个页面至少需要 4 个进程:
-
1 个网络进程
-
1 个浏览器进程
-
1 个 GPU 进程
-
1 个渲染进程
-
如果打开的页面有运行插件的话,还需要再加上 1 个插件进程。
默认情况下,Chrome 会为每个页面分配一个渲染进程,也就是说,每打开一个新页面就会配套创建一个新的渲染进程。
当多个网页是同一站点(same-site)是,共用一个渲染进程。
- 同一站点的定义:根域名(例如,geekbang.org)加上协议(例如,https:// 或者 http://)。包含了该根域名下的所有子域名和不同的端口,以下都是同一站点。
// 它们都是属于同一站点,因为它们的协议都是 HTTPS,而且根域名也都是 geekbang.org。 https://time.geekbang.org https://www.geekbang.org
https://www.geekbang.org:8080
所以,当 n 个网页是同一站点(same-site):
-
1 个网络进程
-
1 个浏览器进程
-
1 个 GPU 进程
-
1 个渲染进程
-
如果打开的页面有运行插件的话,还需要再加上 x 个插件进程。
当 n 个网页不是同一站点(same-site):
-
1 个网络进程
-
1 个浏览器进程
-
1 个 GPU 进程
-
n 个渲染进程
-
如果打开的页面有运行插件的话,还需要再加上 x 个插件进程。
2. HTTP 流程
HTTP 请求过程
一个 HTTP 请求经历了 9 个阶段:
假设:再浏览器地址里键入极客时间网站的地址:http://time.geekbang.org/index.html。
首先会划分为两个流程:
- 浏览器端(的网络线程)发起 HTTP 请求流程,包括 6 个阶段:
- 构建请求、查找缓存、准备 IP 和端口、等待 TCP 队列、建立 TCP 连接、发送 HTTP 请求。
- 服务器端处理 HTTP 请求流程,包括 3 个阶段:
- 处理请求、响应请求、断开 TCP 连接。
(1)浏览器端发起 HTTP 请求
- ⚠️ 构建请求
浏览器构建 请求行 信息,为发起网络请求做数据准备。
GET /index.html HTTP1.1
- ⚠️ 查找缓存
在浏览器缓存中查询是否有要请求的文件。
浏览器缓存是一种在本地保存资源副本,以供下次请求时直接使用的技术。
当浏览器发现请求的资源:
- 在浏览器缓存中存有副本。那么它会拦截请求,返回该资源的副本,并直接结束后续请求。
- 没有发现副本。它会准备发起网络请求。
- ⚠️ 准备 IP 地址和端口
通过 URL 地址,来解析 IP 和端口信息。
IP 地址的获取:域名系统
域名系统:把域名和 IP 地址做一一映射关系。简称 DNS(Domain Name System)。
浏览器会先查找自身的 DNS 数据缓存服务 ,如果域名之前解析过了,浏览器会直接得到 IP 和端口信息。
否则,会向 DNS 服务器申请查找 URL 地址的 IP 信息。
端口号的获取:端口号会在 URL 地址中指明,HTTP 协议默认是 80 端口。
- ⚠️ 等待 TCP 队列
Chrome 有个机制,同一个域名同时最多只能建立 6 个 TCP 连接。
如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。
如果当前请求数量少于 6,会直接进入下一步,建立 TCP 连接。
- ⚠️ 建立 TCP 连接
3 次握手,详见 TCP 相关知识。
- ⚠️ 发送 HTTP 请求
一旦建立了 TCP 连接,浏览器就可以和服务器进行通信了,此时开始传输 HTTP 中的数据。
浏览器会依次发送:请求行、请求头 和 请求体。
下图是 HTTP 的请求数据格式,通过在终端输入
curl -i https://time.geekbang.org/
⚠️ 结构:
- 请求行:浏览器发送请求行是为了就是告诉服务器,当前我需要什么资源。
- 请求方法
- 请求 URI(Uniform Resource Identifier)
- HTTP 版本协议
- 请求头:则传递一些与连接相关的基础信息,比如包含了:
- 浏览器所使用的 操作系统、浏览器内核;
- 当前请求的 域名信息、浏览器端的 Cookie ;
- 等等
- 请求体:存放了浏览器向服务器传递的数据。
⚠️ 请求方法:
常用的请求方法有: Get 和 POST
Get:用于浏览器向服务器获取资源和数据,上文就是一个 Get 请求。
POST:用于浏览器向服务器发送数据,发送的数据保存在 请求体 中。比如登录一个网站,就需要通过 POST 方法把用户信息发送给服务器。
(2)服务器端处理 HTTP 请求
- ⚠️ 处理请求
服务器收到来自浏览器的请求后,会分析请求,然后给出对应响应。
- ⚠️ 响应请求
服务器在收到来自浏览器的请求后开始准备响应的数据,然后通过 服务器性响应 返回给浏览器:
服务器会依次发送:响应行、响应头 和 响应体。
下图是一个服务器响应的数据结构:
服务器会依次发送:响应行、响应头和响应体。
响应行:服务器首先返回 响应行,包括:
- HTTP 协议版本。
- 状态码:通过状态码来告知浏览器,该响应的大致情况。比如 200 表示处理成功,301 表示需要重定向,404 表示没有找到 URL 对应的资源。
响应头:响应头包含了服务器自身的一些信息。比如服务器生成返回数据的时间、返回的数据类型(JSON、HTML、流媒体等类型),以及服务器要在客户端保存的 Cookie 等信息。
响应体:通常,响应体就包含了 HTML 的实际内容。
状态码:301 重定向
当你在浏览器中打开 geekbang.org
后,你会发现最终打开的页面地址是 https://www.geekbang.org。
这两个 URL 之所以不一样,是因为涉及到了一个重定向操作。此时服务器返回的响应行和响应头,可以通过在终端输入以下代码来查看:
curl -I http://time.geekbang.org/
显示如下:
状态码 301,就告知了浏览器,需要重定向。具体含义是:浏览器需要重新导航,请求的 URL 地址应该是响应头的 Location 字段中保存的值。
接下来,浏览器获取 Location 字段中的地址,并使用该地址 重新导航。
- 导航的定义:用户发出 URL 请求到页面开始解析的这个过程,就叫做导航。
- ⚠️ 断开 TCP 连接
通常情况下,一旦服务器向客户端返回了请求数据,就会关闭 TCP 连接。
4 次挥手,详见 TCP 相关知识。