🚀

从输入URL到页面展示, 这中间发生了什么

1. 用户输入

💡
用户输入 URL 并回车, 意味这当前页面即将被替换成新到页面
当前页面执行 beforeunload 事件
  • beforeunload 事件允许页面在退出之前执行一些数据清理操作
  • 还可以询问用户是否要离开当前页面, 比如未提交的表单
  • 用户可以通过 beforeunload 事件来取消导航, 让浏览器不再执行后续工作
 

2. URL 请求过程

浏览器进程会通过进程间通信 (IPC) 把 URL 请求发送至网络进程
网络进程接收到 URL 请求后, 会发起真正的 URL 请求
查找是否有本地缓存. 如果有, 直接将缓存返回给浏览器进程; 如果没有, 那么进入网络请求流程.
网络请求流程
  1. 进行 DNS 解析, 获得 ip 地址
  1. 如果是 HTTPS, 还需要建立 TLS 连接
  1. 利用 IP 地址和服务器建立 TCP 连接
  1. 连接建立之后, 浏览器构建请求行、请求头信息, 并把域名相关的 Cookie 等数据附加到请求头中, 然后向服务器发送请求
  1. 服务器接收到请求后, 会根据请求信息生成响应数据 (响应行、响应头和响应体等内容), 并发送给网络进程
  1. 网络进程接收到响应行和响应头, 就开始解析响应头的内容
网络进程解析响应头
(1) 重定向
  • 如果状态码是 301 或 302, 网络进程会读取 Location 字段中重定向的地址, 重新发起 HTTP 或 HTTPS 请求
  • 如果状态码是 200, 表示浏览器可以继续处理该请求
notion image
(2) 响应数据类型处理
浏览器会根据 Content-Type 的值来决定如何处理响应体的内容
Content-Type 取值
Content-Type: text/html 表示返回的是 HTML 格式内容, 那么浏览器会继续进行导航流程
Content-Type: application/json 表示返回的是 JSON 格式内容
Content-Type: application/octet-stream 表示返回的数据是字节流类型, 浏览器会按照下载类型来处理, 那么该请求会被提交给下载管理器
 
 

3. 准备渲染进程

  • 通常情况下, 浏览器会为每个新页面配套创建一个新的渲染进程
  • 如果从 A 页面打开 B 页面, 并且 A 和 B 都属于同一站点, 那么 B 页面复用 A 页面的渲染进程
    • 官方把这个默认策略叫 process-per-site-instance
💡
同一站点: 相同的协议和根域名
渲染进程准备好之后, 还不能立即进入文档解析状态, 因为此时的文档数据还在网络进程中, 并没有提交给渲染进程, 所以下一步就进入来提交文档的阶段

4. 提交文档

💡
提交文档: 浏览器进程网络进程接收到 HTML 数据提交给渲染进程
提交文档流程
  1. 浏览器进程接收到网络进程的响应头数据之后, 便向渲染进程发起 "提交文档" 的消息
  1. 渲染进程接收到 "提交文档" 的消息后, 会和网络进程建立传输数据的 "管道"
  1. 等文档数据传输完成之后, 渲染进程会返回 "确认提交" 的消息给浏览器进程
  1. 浏览器进程在收到 "确认提交" 的消息后, 会更新浏览器界面状态, 包括安全状态、地址栏的 URL、前进后退的历史状态, 并更新 Web 页面
    1. notion image
💡
这也解释了为什么在浏览器地址栏中输入一个地址后, 之前的页面没有立马消失

5. 渲染阶段

一旦文档被提交, 渲染进程便开始页面解析和子资源加载了
按照渲染的时间顺序, 流水线可分为
1. 构建 DOM 树
DOM 树构建过程示意图
DOM 树构建过程示意图
经过这一过程 DOM 树虽然生成好了, 但是 DOM 节点的样式依然是未知的
要让 DOM 节点拥有正确的样式, 就需要样式计算了
2.样式计算 (Recalculate Style)
样式计算阶段大体分为三步
1.把 CSS 转换为浏览器能够理解的结构 —— styleSheets
CSS 样式来源主要有三种
  • link 引入的外部 CSS 文件
  • <style> 标签内的 CSS
  • 元素的内联样式 style 属性
💡
和 HTML 文件一样, 浏览器无法直接理解这些纯文本 CSS 样式, 渲染引擎会将 CSS 文本转换为浏览器可以理解的结果 —— styleSheets
document.styleSheets 可以查看转换后的 styleSheets
2.转换样式表中的属性值, 使其标准化
很多属性, 如 2em、blue、bold, 这些类型数值不容易被渲染引擎理解
因此渲染引擎需要将所有值转换为容易理解、标准化的计算值
notion image
计算出 DOM 树中每个节点的具体样式
根据 CSS 的继承规则层叠规则 (定义了如何合并来自多个源的属性值的算法) 计算出 DOM 树每个节点的具体样式
3.布局阶段
chrome 在布局阶段需要完成两个任务
1.创建布局树
💡
因为 DOM 树包含很多不可见元素 (比如 head 标签, 使用了 display: none 元素), 所以在显示之前, 还需要额外构建一棵只包含可见元素布局树
布局树构造过程
布局树构造过程
构建布局树流程
  • 遍历 DOM 树中的所有可见节点, 并把这些节点加到布局树中
  • 不可见节点会被忽略掉
2.布局计算
TODO
4.分层
 
5.绘制
6.分块
7.光栅化和合成