浏览器基础:进程与线程

来自Wikioe
Eijux讨论 | 贡献2023年3月25日 (六) 08:02的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索


关于

学习 JavaScript 的“事件循环(Event Loop)”机制时,需要结合浏览器的进程、线程相关知识。


关于浏览器的更多知识,参考:
# 《浏览器工作原理(各线程介绍)》
# 《深入理解浏览器中的进程与线程》
# 《深入浏览器之页面加载中的计算机网络》
# 《深入浏览器之浏览器中的进程与线程》
# 《浏览器进程/线程模型》

浏览器进程/线程模型[1]

浏览器进程架构有两种方案:单进程多线程多进程(通过IPC传递消息)

Different browser architectures in process/thread-diagram.png

  1. 单进程多线程:顾名思义,浏览器在同一个进程运行所有功能模块(包括篇:网络、插件、JavaScript 运行环境、渲染引擎和页面等)
  • 其缺点很明显:
    1. 不稳定:任一线程错误,将导致整个进程崩溃
    2. 不流畅:同一时刻只有一个浏览器模块可用
    3. 不安全:各线程共享进程数据,更容易导致攻击
    4. 高占用:进程关闭之前,不会回收由线程占用的资源
  • (其实早在 2007 年之前,市面上浏览器都是单进程的)

“多进程”模型

现代浏览器多从用多进程模型,但各家实现细节各有差异。

(以 Chrome 为例)

Diagram of Chrome’s multi process architecture.png

浏览器主要进程,包括:

  1. 浏览器进程(Browser Process):控制应用程序的“chrome”部分,包括地址栏、书签、后退和前进按钮。还处理网络浏览器中不可见的特权部分,如网络请求和文件访问。
    • 简单来说:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  2. 渲染进程(Renderer Process):控制显示网站的选项卡内的任何内容。
    • 浏览器会为每个 Tab 标签创建一个渲染进程
    • 出于安全考虑,渲染进程都是运行在沙箱模式下。
  3. GPU进程(GPU Process):处理应用程序的 GPU 任务,并将它们绘制在同一个表面上。
  4. 插件进程(Plugin Process):控制网站使用的任何插件。
    • 每个插件都有一个插件进程。
也有说法,当前 Chrome 架构(面向服务的架构)将“网络进程”、“utility进程”从“浏览器进程”中独立了出来[2] ,但此处不重要。

Different processes pointing to different parts of browser UIavif.png

浏览器:内核、引擎[3]

浏览器相关的术语:浏览器内核、浏览器引擎、排版引擎、Js引擎、Blink、v8、webkit……,这都是啥?

浏览器内核(浏览器引擎):指“广义上的渲染引擎”(渲染引擎 + JS 引擎)

  1. 渲染引擎(排版引擎):负责解析(HTML、CSS、JavaScript 和 DOM),并渲染页面。
    如:WebKit、Geck、Blink
  2. JS 引擎(JS 虚拟机):负责解释、执行 JavaScript 代码
    如:SpiderMonkey、JavaScriptCore(WebKit 内置)、V8


常见浏览器的“渲染引擎”和“JS 引擎”
浏览器 渲染引擎 JS 引擎
IE Trident(MSHTML) JScript/Chakra
Edge EdgeHTML Chakra
Chrome Blink V8
Firefox Gecko SpiderMonkey
Safari WebKit JavaScriptCore
Opera Presto Carakan


“排版引擎”(Blink)和“Javascript引擎”(V8)都是运行在“渲染进程”(Renderer Process)中,通过“Event Loop”进协调[4]

渲染进程

浏览器的“渲染进程(Renderer Process)”是多线程的,页面的渲染、JS 执行等都在这个进程内进行,其执行机制就是“Event Loop:事件循环”。

“渲染进程”中包括以下线程:

  1. GUI 渲染线程:负责渲染浏览器界面(解析 HTML、CSS;构建 DOM 树、RenderObject 树;布局、绘制)。
    • 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。
  2. JS 引擎线程:负责解析处理 JavaScript 任务(包括:“执行栈”、“任务队列”),运行代码。
    • 一个 Tab 页中只有一个“JS 引擎线程”。
  3. 事件触发线程:负责检测“事件触发”状态。
    当事件发条件被触发时,该线程会:把对应事件添加到“事件队列”(宏任务)中,以等待“JS 引擎”执行;
  4. 定时触发器线程:负责检测“定时器”状态。
    当计时完毕后,该线程会:把对应事件添加到“事件队列”(宏任务)中,以等待“JS 引擎”执行;
    • setInterval 与 setTimeout 所在线程。
  5. 异步http请求线程:负责检测 HTTP 请求状态。
    当请求状态变更时,该线程会:把对应事件添加到“事件队列”(宏任务)中,以等待“JS 引擎”执行;
    • 在 XMLHttpRequest/Fetch 连接后,由浏览器创建的线程。


“GUI渲染线程”与“JS 引擎线程”互斥:

    JS 堵塞的原因所在,其目的是:防止渲染出现不可预期的结果(毕竟 JS 是可以操作 DOM 的)。

参考