# 3.浏览器的多进程、线程架构
# Chrome 架构:仅仅打开了 1 个页面,为什么有 4 个进程
# 首先讲一下进程特点
- 进程中的任意一线程执行出错,都会导致整个进程的崩溃
- 线程之间共享进程中的数据
- 当一个进程关闭之后,操作系统会回收进程所占用的内存
- 进程之间的内容相互隔离。
- 单进程缺点
- 不稳定
- 不流畅
- 不安全(因为特点 2,页面插件可以直接获取操作系统任意资源,)
# 现代浏览器
所以最基本运行一个页面,就需要四个进程:1 个网络进程、1 个浏览器进程、1 个 GPU 进程以及 1 个渲染进程
# 五个进程的作用
主进程
- 协调控制其他子进程(创建、销毁)
- 浏览器界面显示,用户交互,前进、后退、收藏
- 将渲染进程得到的内存中的 Bitmap,绘制到用户界面上
- 处理不可见操作,网络请求,文件访问等
第三方插件进程
- 每种类型的插件对应一个进程,仅当使用该插件时才创建
GPU 进程
- 用于 3D 绘制等
渲染进程,就是我们说的浏览器内核
- 负责页面渲染,脚本执行,事件处理等
- 每个 tab 页一个渲染进程
网络进程。
- 主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
# 关于最主要的:渲染进程
渲染进程是多线程的,它主要包含了以下六个线程:GUI 线程,js 引擎线程,定时器触发线程,事件触发线程,异步 http 请求线程,合成线程,io 线程。
- 主线程(GUI, JS):负责:DOM、Style、layout、paint、layer
- 合成器线程:frame、tiles
- 栅格线程:raster、draw quads
- 事件触发线程
js 和渲染都在主线程运行,所以当有长时间 js 任务的时候,会造成页面卡顿 而 CSS 的 transform 属性,是在合成器线程中,所以不会影响主线程的进行。
两个线程合并称为:主线程(UI 线程)
- GUI 渲染线程
- 负责渲染页面,布局和绘制
- 页面需要重绘和回流时,该线程就会执行
- 与 js 引擎线程互斥,防止渲染结果不可预期
- JS 引擎线程
- 负责处理解析和执行 javascript 脚本程序
- 只有一个 JS 引擎线程(单线程)
- 与 GUI 渲染线程互斥,防止渲染结果不可预期
- GUI 渲染线程
工作线程(也就是事件循环机制触发的地方,包含了微任务和宏任务)
- 事件触发线程
- 用来控制事件循环(鼠标点击、setTimeout、ajax 等)
- 当处理一些不能立即执行的代码时,会将对应的任务在其可以触发的时机,添加到事件队列的末端
- 事件循环机制会在 JS 引擎线程空闲时,循环访问事件队列的头部,如果有函数,则会将该函数推到执行栈中并立即执行
- 定时触发器线程
- setInterval 与 setTimeout 所在的线程
- 定时任务并不是由 JS 引擎计时的,是由定时触发线程来计时的
- 计时完毕后,将回调事件放入到事件队列中
- web worker
- 异步 HTTP 请求(现在已经被提取出来作为一个单独的进程了)
- 事件触发线程
合成器线程(即 transform 运行的层级)
光栅线程