现代 Chrome 浏览器架构设计

#bom #浏览器

目录

1. 关键点

  • 主进程:
  • 渲染进程
    • 主线程:
      • ==单线程==,js html css等
    • worker 线程
    • 合成线程
    • 光栅线程
    • 定时器线程
    • 事件线程
    • 垃圾回收线程
    • 调试器线程

2. Chrome 多进程架构:浏览器的 6 个主要进程

  1. 浏览器==主进程 / UI 进程==(Browser Process):
    • 负责管理用户界面、地址栏、书签栏等,以及协调其他进程
  2. 渲染进程(Renderer Process):==负责将HTML、CSS和JavaScript 转换为用户可以交互的网页==
    • 渲染进程负责站点的渲染,其中也包括 JavaScript 代码的运行web worker 的管理等
    • 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页
      • 排版引擎Blink和JavaScript引擎V8都是运行在该进程
  3. 插件进程:扩展进程(Extension Process)
    • 运行网页插件,如Flash
    • 运行浏览器扩展
  4. GPU 进程:
    • 处理GPU相关的任务,加速网页渲染
  5. 网络进程(Network Process):处理网络请求
    • Chrome有个机制,同一个域名同时最多只能建立 6 个TCP连接
      • 如果在同一个域名下同时有10个请求发生,那么其中 4个请求会进入排队等待状态,直至进行中的请求完成

3. 在每个渲染进程中,又包含多个线程

  • 主线程:执行 JavaScript,处理 DOM、CSS 等
    • JavaScript 主要在渲染进程的主线程上执行,所以长时间运行的 JavaScript 会阻塞页面渲染
  • 工作线程(Worker Thread):
    • 执行 Web Worker 或 Service Worker。
  • 合成线程(Compositor Thread):
    • 负责将页面各个部分合成为最终显示的图像。
  • 光栅线程(Raster Thread):
    • 将页面元素转换为位图

4. Chrome 的 4 种进程模型

Chrome有四种进程模型,默认使用的是 Process-per-site-instance 模型

  • 同一站点(相同协议和域名)的多个标签页通常会共用一个渲染进程
  • 不同站点的标签页会使用不同的渲染进程

其他的还有

  • Process-per-site
  • Process-per-tab
  • Single Process

Chrome会根据系统的资源情况动态调整进程的分配:

  • 在资源充足的系统上,它可能会为每个标签页分配独立的进程
  • 在资源受限的系统上,它可能会合并一些进程以节省资源

Chrome 允许用户或管理员通过命令行参数来选择不同的进程模型

5. Chrome 常见的线程

Chrome 采用多进程多线程架构,每个进程内部都有多个线程协同工作。以下是一些主要的线程:

  • 主线程(Main thread)
    • 负责处理大部分的渲染工作,包括 DOM 树的构建、样式计算、布局计算等。
    • 执行 JavaScript 代码。
    • 处理用户交互事件。
  • 合成线程(Compositor thread):
    • 负责将页面的各个部分合成为最终显示的图像。
    • 处理一些与滚动相关的操作,提高页面滚动的流畅度。
  • 渲染线程(Renderer thread):
    • 在 Renderer 进程中,负责页面渲染的主要工作。
    • 与主线程密切协作,处理页面的可视化呈现。
  • IO 线程:
    • 负责处理==文件系统操作和网络请求==
    • 在浏览器主进程和渲染进程中都存在 IO 线程
  • 工作线程(Worker threads):
    • 用于执行 Web Workers,允许在后台运行 JavaScript 代码而不影响主线程。
  • 光栅化线程(Raster threads):
    • 负责将页面的各个部分转换为位图。
    • 通常有多个光栅化线程并行工作,以提高性能。
  • GPU 线程:
    • 在 GPU 进程中,负责与 GPU 硬件交互,加速图形渲染。
  • 网络线程:
    • 在网络进程中,处理所有的网络请求和响应。
      • 比如Ajax请求、Fetch等都是
  • 定时器线程
    • 记住,浏览器的setIntervalsetTimeout不是js引擎里的,而是浏览器自己开了个线程来处理
    • 负责处理 setTimeoutsetInterval 等计时器功能。
  • 事件触发线程
    • 管理事件队列,当事件被触发时,将其添加到队列中等待主线程处理。
      • JS 引擎自己忙不过来,需要浏览器另开线程协助
  • 垃圾回收线程
    • 负责 JavaScript 的内存垃圾回收,以释放不再使用的内存。
  • 插件线程:
    • 用于运行浏览器插件,每个插件可能在自己的线程中运行。
  • ==调试线程==:
    • 用于支持开发者工具和日志记录,帮助诊断问题和性能分析。

需要注意的是,虽然 Chrome 是==多线程==的,

  • 但 JavaScript 在浏览器中仍然是单线程执行的(除非使用 Web Workers)。
  • 这种设计是为了简化编程模型,避免复杂的线程同步问题
  • 同时也与 JavaScript 的主要用途
    • 处理用户交互和操作 DOM 相符合。

6. JavaScript 引擎 与 Chrome 其他线程的关系

总的来说,JavaScript 引擎(V8)是 Chrome 浏览器渲染进程的核心组件之一

  • 在专门的线程上运行,负责执行 JavaScript 代码,但同时也与浏览器的其他部分(如 GUI 渲染、事件处理、网络请求等)紧密协作

这种设计既保证了 JavaScript 的执行效率,又维护了浏览器的整体性能和安全性。

理解 JavaScript 引擎与浏览器进程线程架构的关系,对于开发高性能的 Web 应用和理解浏览器的工作原理都非常重要。

  • JavaScript 引擎与渲染进程:
    • JavaScript 引擎(V8)运行在浏览器的渲染进程(Renderer Process)中
    • 渲染进程是负责将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页的核心进程。
    • 在同一个渲染进程中,除了 JavaScript 引擎,还包括==排版引擎==(如 Blink)
  • JavaScript 引擎线程:
    • JavaScript 引擎在渲染进程中运行在一个专门的线程上,通常被称为 JS 引擎线程或主线程
    • 这个线程负责解析和执行 JavaScript 代码。
  • GUI 渲染线程的关系:
    • JavaScript 引擎线程和 GUI 渲染线程是互斥的。
      • 这意味着当 JS 引擎执行时,GUI 渲染线程会被挂起。
      • 这种设计是为了防止渲染出现不可预期的结果。
      • 所以,当 JavaScript 执行时间过长,可能会导致页面渲染的卡顿。
  • 事件循环和消息队列
    • JavaScript 是单线程的,但通过事件循环(Event Loop)和消息队列来处理异步操作
      • 事件循环和消息队列的机制
        • 允许 JavaScript 在不阻塞主线程的情况下处理 I/O 操作、定时器等异步任务
  • 与其他进程的交互:
    • JavaScript 引擎运行在渲染进程中
      • 但它可以通过进程间通信(IPC)与其他进程(如浏览器主进程、网络进程等)进行交互
      • 这种交互允许 JavaScript 执行网络请求、访问本地存储等操作
  • Web Workers:
    • 为了解决 JavaScript 单线程的限制,现代浏览器支持 Web Workers。
    • Web Workers 允许在后台线程中运行 JavaScript,不会直接影响主线程的执行。
    • 但是,Web Workers 不能直接操作 DOM,它们主要用于执行耗时的计算任务。
  • V8 引擎的优化:
    • V8 引擎内部有多个线程协同工作,如编译线程、优化线程和垃圾回收线程。
    • 这些内部线程帮助 V8 实现 JIT(即时编译)、代码优化和内存管理,提高 JavaScript 的执行效率。
  • 沙箱隔离:
    • JavaScript 引擎在渲染进程中运行,这种设计提供了一定程度的安全隔离。
    • 每个标签页通常运行在独立的渲染进程中,这意味着一个标签页中的 JavaScript 代码不能直接访问或影响其他标签页。