Skip to main content

浏览器

以 Google Chrome 为例,chrome 是一个多进程架构

浏览器进程

  • 浏览器进程。主要负责处理浏览器的界面交互、子进程管理、存储等功能
  • 渲染进程
    • GUI 渲染线程
    • js 引擎线程(和 GUI 互斥)
    • 定时器触发线程
    • 事件触发线程
    • 异步 http 请求线程
    • IO 线程
    • ...
  • GPU 进程。绘制 UI 界面
  • 网络请求进程。处理页面网络请求和加载资源
  • 插件进程

出于安全考虑,渲染进程和插件进程都是运行在沙箱模式下

需要注意的是,这些进程中,浏览器主进程、网络进程、GPU 进程都是所有 Tab 共用的

五层网络协议体系结构

  • 应用层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层

输入 url 到响应发生了什么

主要流程如下:

  1. 输入判断。判断输入为 URL 还是搜索内容,如果为 URL,就将 URL 通过 IPC(进程间通信)传给网络请求进程并由它发起请求。
  2. http 资源缓存检查。
  3. DNS 解析。解析域名并返回对应的 IP 地址,浏览器会做缓存。(如果是 https,还会建立 TLS 连接)
  4. TCP 连接。TCP 三次握手
  5. 发送 HTTP 请求。
  6. 服务器处理请求并返回响应数据给网络进程。解析响应头时,可能发生重定向。
    1. 浏览器进程接收到网络进程解析好的响应头数据,向渲染进程 提交文档
    2. 渲染进程和网络进程建立传输数据的管道
    3. 等文档数据传输完成,渲染进程会返回 确认提交 的消息给浏览器进程
    4. 浏览器进程收到确认提交的消息,会更新浏览器界面和 web 页面
  7. 浏览器解析渲染页面。
    1. 构建 DOM 树
    2. 样式计算。转换 css 文本为 styleSheets,并转换样式表中的属性值,使其标准化。计算 DOM 树种每个节点的具体样式
    3. 布局。计算 DOM 树种可见元素的几何位置
    4. 分层。
    5. 绘制。
    6. 栅格化。
    7. 合成和显示。
  8. 断开连接。TCP 四次挥手

同一站点:指的是具有相同协议和根域名的网页。如果从一个页面中打开另一个属于相同站点的页面,新页面将复用该页面的渲染进程

更详细内容可以参见 超详细过程

浏览器缓存

当浏览器再次访问一个已经访问过的资源时,它会这样做:

  • 看看是否命中强缓存,如果命中,就直接使用缓存
  • 如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存
  • 如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存
  • 否则,返回最新的资源

DNS

从一个域名到一个 IP 地址到底发生了什么?

  • 浏览器查询自己的缓存中是否有该域名的访问记录,如果有的话直接访问对应的 IP 地址,否则进行下一步
  • 查询本地 host 文件,否则进行下一步
  • 进入路由器缓存中查找,以上均为客户端的 DNS 缓存,找不到就进入下一步
  • 进入 ISP 的 DNS 缓存中查询,比如电信的 DNS 缓存服务器;否则进入下一步
  • 进入根服务器、顶级域名服务器、主域名服务器进行查询,如果没有找到就进入下一级域名服务器查找,并重复该步骤直到找到正确记录
  • 本地域名服务器将返回的结果保存到缓存中,客户端通过这个 IP 地址与 web 服务器建立链接。

浏览器渲染页面

  1. 浏览器获取 HTML 文件,然后对文件进行解析,形成 DOM Tree
  2. 与此同时,进行 CSS 解析,生成 Style Rules
  3. 接着将 DOM Tree 与 Style Rules 合成为 Render Tree
  4. 接着进入布局(Layout)阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标
  5. 随后调用 GPU 进行绘制(Paint),遍历 Render Tree 的节点,并将元素呈现出来

回流(Reflow)和重绘(Repaint)

  • 回流是指页面中某些元素发生变化而影响了布局时(如尺寸、位置改变),浏览器需要重新布局并绘制的过程。
  • 重绘是指页面中某些元素发生了不影响布局的变化时(如颜色改变),浏览器重新绘制的过程。
  • 回流一定会包括重绘,所以回流会更影响性能,在实际操作中,要尽量减少回流。