浏览器多进程与js单线程


2019/11/28 进程 & 线程

# 整体概念

# 对比工厂和工人

  • 类似于一个工厂,有自己独立的资源(系统为进程分配的独立内存)
  • 工厂之间相互独立(进程之间相互独立)
  • 工厂中有一个或多个工人(进程管理一个或多个线程程)
  • 多个工人协作完成任务(进程中的线程互相协作)
  • 工人之间共享工厂资源(同一进程下的各个线程之间共享程序的内存空间:包括代码段、数据集、堆等)

# 官方一些的描述

  • 进程
    • 是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)
    • 不同进程之间可以通信,代价较大
    • 浏览器每打开一个 tab 页,就相当于创建了一个独立的浏览器进程(浏览器有自己的优化机制,某些契机下会合并进程)
  • 线程
    • 是cpu调度的最小单位
    • 是建立在进程的基础上的一次程序运行单位
    • 一个进程中可以有多个线程
    • 线程之间各司其职、互相协作,共同完成一个进程中的工作

# 浏览器多进程

# 包含的主要进程

浏览器中包含的主要进程:

  1. 浏览器主进程
  2. 第三方插件进程
  3. GPU进程
  4. 渲染进程(浏览器内核)

可以打开 Chrome 的 更多工具 -> 任务管理器 查看

# 浏览器主进程(唯一)

  • 浏览器中起管理作用:
    1. 界面显示、用户交互(前进,后退等)的管理
    2. 各页面进程的管理
    3. 其他进程创建和销毁的管理
    4. 网络资源的管理与下载
  • 与渲染相关的作用:
    • 将渲染进程(内核)得到的内存中的 Bitmap ,绘制到用户界面

# 第三方插件进程

  • 每种类型的插件对应一个进程
  • 仅当使用该插件时才创建

# GPU进程(唯一)

  • 用于3D绘制等

# 渲染进程(每个tab页一个)

  • 又称为 浏览器内核
  • 流行的浏览器内核
    • WebKit - 原Chrome、Safari
    • Blink - Chrome
    • Gecko - Firefox
    • Trident - IE(不开源)
  • 每个渲染进程之间互不影响
  • 主要作用:
    • 页面渲染
    • 脚本执行
    • 事件处理

# 浏览器多进程的优势

  1. 避免单个页面、插件崩溃导致浏览器崩溃
  2. 多进程充分利用多核优势
  3. 方便使用沙盒模型隔离插件等进程,提高浏览器稳定性

# 渲染进程中包含的常驻线程

一个浏览器渲染进程中包含的常驻线程:

  1. 界面渲染线程
  2. JS引擎线程
  3. 事件触发线程(异步任务队列)
  4. 定时触发器线程
  5. 异步http请求线程

# 界面渲染线程

  • 负责浏览器界面渲染,解析 HTML 构建DOM树,解析 CSS 构建CSSOM树 等
  • 重绘(Repaint)、回流(reflow)
  • JS引擎线程 互斥,JS引擎线程有任务执行时,界面渲染线程将被挂起(GUI更新会被保存在一个队列中),等到JS引擎线程空闲时立即执行执行
  • 互斥的原因:JS引擎执行的脚本有可能修改UI界面,界面渲染脚本执行同时进行时可能导致渲染出错

# JS引擎线程

  • 又叫 js内核(一个进程中唯一)
  • js单线程:一个渲染进程中唯一存在一个JS引擎线程
  • 流行的js引擎
    • SpiderMonkey(Mozilla) - 第一款JavaScript引擎
    • TraceMonkey(Mozilla) - 基于实时编译的引擎
    • V8(Google) - Chrome、NodeJS使用的js引擎
    • KJS(Konqueror) - KDE的ECMAScript/JavaScript引擎
  • 负责处理Javascript脚本程序
  • JS引擎的表现形式:循环查看当前队列中是否存在事件需要执行,当JS引擎线程闲置时,会去事件触发线程查看是否存在异步事件,有则拉取过来作为一次循环再次执行
  • JS引擎的一次循环被称为一次宏任务执行
  • 界面渲染线程 互斥,JS引擎线程 将阻塞 界面渲染线程

# 事件触发线程(异步任务队列)

  • 归属于浏览器
  • 控制事件循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)
  • 引擎读取到的异步(setTimeout)、事件脚本(click),会将对应任务添加到事件线程中
  • 当保存的任务符合条件触发时,事件触发线程会将事件添加到 -> 待处理队列的队尾,等待JS引擎线程空闲时处理

# 定时触发器线程

  • setIntervalsetTimeout 所在线程
  • 通过单独线程来计时并触发定时
  • 当触发定时器时,定时触发器线程会将事件添加到 -> 事件触发线程的待处理队列的队尾,等待JS引擎线程空闲时处理
  • tip: W3C标准中规定:要求setTimeout中低于4ms的时间间隔算为4ms

# 异步http请求线程

  • 在 XMLHttpRequest 在连接后是通过浏览器新开一个线程请求
  • 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调添加到 -> 事件触发线程的待处理队列的队尾,等待JS引擎线程空闲时处理

# 浏览器主进程与渲染进程的通信

浏览器进程通信

打开一个浏览器的线程通信:

  1. 浏览器主进程收到用户请求,首先需要获取页面内容(譬如通过网络下载资源),随后将该任务通过RendererHost接口传递给界面渲染进程
  2. 界面渲染进程的Renderer接口收到消息,简单解释后,交给渲染线程,然后开始渲染
  3. 渲染线程经由界面渲染进程帮助计算元素位置、排列、绘制,得到结果(Bitmap)
  4. 浏览器主进程收到结果(Bitmap)将其渲染出来
Last Updated: 12/2/2019, 9:23:57 AM