Skip to content

Chrome 架构

进程与线程

每一个执行中的程序可以理解为 进程, 一个进程由多个线程组成

一个进程中任意一个线程出错, 就会导致整个进程出错

一个进程中的所有线程共享进程中的数据

不同进程之间的内容相互隔离

关闭进程时, 进程中的所有线程也会关闭

进程

进程是 CPU 资源分配的最小单位

线程

线程是 CPU 调度的最小单位

区别

  1. 进程是资源分配的最小单位, 线程是程序执行的最小单位

  2. 进程有自己的独立地址空间, 每启动一个进程, 系统就会为它分配地址空间, 建立数据表来维护代码段、堆栈段和数据段, 这种操作非常昂贵. 而线程是共享进程中的数据的, 使用相同的地址空间, 因此 CPU 切换一个线程的花费远比进程要小很多, 同时创建一个线程的开销也比进程要小很多

  3. 线程之间的通信更方便, 同一进程下的线程共享全局变量、静态变量等数据, 而进程之间的通信需要以通信的方式(IPC)进行. 不过如何处理好同步与互斥是编写多线程程序的难点

  4. 但是多进程程序更健壮, 多线程程序只要有一个线程死掉, 整个进程也死掉了, 而一个进程死掉并不会对另外一个进程造成影响, 因为进程有自己独立的地址空间

单进程浏览器架构

进程包含 网络、插件、js 运行环境、渲染引擎等模块

缺点

  • 不稳定

一个模块的崩溃会引起整个浏览器的崩溃

  • 不流畅

  • 不安全

多进程浏览器架构

最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程

浏览器进程

界面显示、用户交互、子进程管理, 同时提供存储等功能

渲染进程

核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页, 排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中, 默认情况下, Chrome 会为每个 Tab 标签创建一个渲染进程. 出于安全考虑, 渲染进程都是运行在沙箱模式下

渲染进程中的几种线程:

  • 主线程

    主线程是浏览器渲染进程中最重要的线程之一, 负责处理用户输入、执行 JavaScript 代码、更新 DOM 和样式信息等任务. 在主线程中运行的任务会按照事件循环模型依次执行, 确保页面的交互和渲染能够顺利进行

  • 渲染线程

    渲染线程负责将 HTML、CSS 和 JavaScript 转换为可视化页面, 包括布局计算、绘制和合成图层等操作. 在渲染线程中, 会生成页面的渲染树(Render Tree), 并使用 GPU 进行加速渲染

  • 定时器线程

    定时器线程用于处理通过 setTimeout 和 setInterval 等方法设置的定时任务. 它负责在指定时间后将任务添加到主线程的任务队列中执行

  • 事件线程

    事件线程用于处理各种事件, 如鼠标点击、键盘输入等用户交互事件. 当事件发生时, 会被添加到事件队列中, 在主线程空闲时被依次处理

GPU 进程

UI 界面都选择采用 GPU 来绘制

网络进程

主要负责页面的网络资源加载, 之前是作为一个模块运行在浏览器进程里面的, 直至最近才独立出来, 成为一个单独的进程

插件进程

主要是负责插件的运行, 因插件易崩溃, 所以需要通过插件进程来隔离, 以保证插件进程崩溃不会对浏览器和页面造成影响

渲染流程

整个渲染流程分为: 构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成

  • 构建 DOM 树

    解析 HTML 文件转换为 DOM 树

  • 构建 CSSOM 树

    解析 CSS 文件, 构建 CSSOM 树

  • 布局

    将 DOM 树和 CSSOM 树合成 渲染树, 其中只需要包含显示的节点和样式信息

  • 分层

    对渲染树进行分层操作, 生成分层树

  • 图层绘制

    对每个图层生成绘制列表, 提交到合成线程

  • 栅格化

    合成线程将图层分成不同的图块, 并通过栅格化将图块转化为位图

  • 合成与显示

    合成线程给浏览器进程发送绘制指令

重绘

当计算好盒模型的位置、大小及其他属性后, 浏览器根据每个盒子特性进行绘制

元素绘制属性变化, 触发重绘, 重绘省去了布局和分层阶段,执行效率高于重排

  • 颜色的修改
  • 文本方向的修改
  • 阴影的修改

直接合成阶段

无需布局和绘制, 只执行合成操作

其他

script defer async

Released under the MIT License.