大家好,我是半虹,这篇文章来讲浏览器架构


1、相关概念

  • 进程:是操作系统资源分配的最小单位
  • 线程:是操作系统进行调度的最小单位,一个进程中包含多个线程,这些线程共享该进程资源

  • CPU:中央处理单元,负责处理各类基础计算任务
  • GPU:图形处理单元,可以高效并行矩阵计算任务

2、典型架构

浏览器的实现并没有统一的标准,不同的浏览器会有着不同的实现

其中最为经典的两种架构,一是单进程多线程,二是多进程多线程

目前主流浏览器大多都是多进程多线程的架构,就以 Chrome 为例,核心进程及其功能列举如下:

  • 浏览器进程 :通常是一个,是浏览器主进程

           负责浏览器中基本界面的展示和交互(例如书签、地址栏、前进后退按钮)

           以及浏览器中其他底层的功能的执行(例如网络请求、文件访问)

  • 渲染器进程 :通常有多个,是浏览器的内核,包括有排版引擎和 JavaScript 引擎都运行其中

           负责标签页内相关事务的处理,包括有页面渲染、脚本执行、事件处理等

           每个标签页对应一个渲染进程(也并不一定如此,这个后文会进行说明)

  • GPU 进程 :负责处理 GPU 任务

  • 插件 进程 :负责运行浏览器插件,例如 flash

使用多进程的架构具有以下优势

  1. 更高的稳定性:每个标签页对应着一个渲染进程,如果有一个标签页崩溃,只会影响对应的渲染进程
  2. 更好的安全性:每个标签页对应着一个渲染进程,标签页之间相互有隔离

浏览器中多个进程如何协同工作呢?先来简单概述下

当在地址栏中输入 URL,浏览器进程会向这个 URL 发送请求,获取对应的 HTML

然后返回的 HTML 会交给渲染器进程,渲染器进程解析 HTML 内容

解析过程中 ,如果需要请求网络资源,那么交回给浏览器进程加载

在此过程中 ,插件进程加载插件资源,执行插件的代码

解析完成后 ,渲染器进程计算图像帧,并将图像帧交给 GPU 进程绘制在屏幕上

整个架构中,有两个比较关键的进程,一是浏览器进程,二是渲染器进程

渲染器进程留到下篇文章再讲,这里先介绍浏览器进程,浏览器进程包括以下重要的线程

  • network 线程:主要用于控制网络请求
  • storage 线程:主要用于控制文件访问
  • UI 线程: 控制浏览器上的按钮以及基础界面的展示
  • IO 线程: 主要用于进程间通信

下面就以浏览器的导航为例,详细讲讲各线程进程如何协同工作

这也是从浏览器的角度解答从输入URL到页面显示所经历的过程

  1. 处理输入

    当在浏览器导航栏输入内容并按下确认后,UI 线程会判断所输入的内容是搜索关键词还是 URL

    若是搜索关键词,则会转化为默认搜索引擎所对应的 URL,若本来就是 URL,则不做处理

  2. 开始导航

    UI 线程将上述的 URL 交给 network 线程,并将标签页前的图标展示为加载中的状态

    network 线程会进行一系列如 DNS 寻址、建立 TLS 连接等网络操作来请求对应资源

    如果收到服务器重定向头部,network 线程会与 UI 线程进行沟通,并发起新的请求

  3. 读取响应

    network 线程收到服务器响应后,解析 HTTP 报文,并根据响应头 Content-Type 确定响应主体类型

    如果是 HTML 文件,则将响应数据交给渲染器进程,如果是 zip 或者是其他文件,则交给下载管理器

    network 线程若要将内容交给渲染进程,则需要先对内容做 SafeBrowsing Check 以及 CORB Check

  4. 寻找渲染进程

    network 线程做完所有检查,并确认浏览器能导航到该站点后,告诉 UI 线程所有数据都已经准备好

    UI 线程在收到 network 线程确认后,会为该站点寻找一个渲染进程渲染界面

    因 网络请求要几百毫秒后才可以完成,为了缩短导航时间,浏览器会进行优化

    例如,在 UI 线程将 URL 发送给 network 线程时,其实已经知道要导航的站点

    所以在 network 线程工作时, UI 线程可以提前为该站点启动一个新的渲染进程

    若一切顺利,network 线程准备好数据后,渲染器进程也准备就绪,这样就能节省新建进程的时间

  5. 提交导航

    到此为止,数据和渲染器进程都已准备好,浏览器进程会通过 IPC 告诉渲染器进程去提交本次导航

    除此之外,浏览器进程还会将响应数据流传递给对应的渲染器进程让其继续去接收 HTML 数据

    一旦浏览器进程接收到渲染器进程的回复,导航过程结束,文档加载阶段正式开始( 下篇文章介绍

  6. 初始加载完成

    导航提交完成后,渲染器进程就开始加载资源并渲染页面

    页面渲染完成后,渲染器进程就通过 IPC 通知浏览器进程

    浏览器进程中 UI 线程会停止展示标签页前的加载中图标

本文到此也基本结束,最后再来填一个坑,就是上面也有提到,并不一定每个标签页对应一个渲染器进程

实际上,浏览器为了节省内存使用,提供有多种进程模式可选,每种模式有着不同的行为:

  1. Process-per-site-instance:默认模式,打开新的站点创建新的进程

    但在旧页面打开新页面,且新页面与旧页面都属于同一站点那么共用进程

  2. Process-per-site:每个站点共用一个进程

  3. Process-per-tab:每个页面共用一个进程

  4. Single Process:单进程


好啦,本文到此结束,感谢您的阅读!

如果你觉得这篇文章有需要修改完善的地方,欢迎在评论区留下你宝贵的意见或者建议

如果你觉得这篇文章还不错的话,欢迎点赞、收藏、关注,你的支持是对我最大的鼓励 (/ω\)