理解浏览器的进程与线程
- Chrome架构:仅仅打开了1个页面,为什么有4个进程
- 区分进程与线程
- 浏览器是多进程的
- 浏览器的渲染进程是多线程的
- 多标签之间怎么通信
Chrome架构
-仅仅打开了1个页面
区分进程与线程
- 线程和进程都是
cpu
工作时间片的一个描述 - 进程是cpu
资源分配
的最小单位(是能拥有资源和独立运行的最小单位) - 线程是
cpu调度
的最小单位(线程是建立在进程的基础上的一次程序运行
单位,一个进程中可以有多个
线程)
一辆火车可以有多个车厢,单纯的车厢无法运行
- 不同进程之间也可以通信(传递数据),不过代价较大 - 进程通信管道
IPC机制
相当于一辆火车上的乘客很难换到另外一辆火车,比如站点换乘
- 进程中的任意一线程执行出错,都会导致整个
进程崩溃
一列火车上中间的一节车厢着火了,将影响到所有车厢
- 进程间
互不影响
一列火车不会影响到另外一列火车
- 当一个进程关闭之后,操作系统会
回收
该进程的内存空间
浏览器是多进程的
浏览器有五种进程:1个浏览器进程,1个GPU进程,1个网络进程,多个渲染进程,和 多个插件进程
浏览器进程
: 负责控制浏览器除标签页外的界面
,包括地址栏、书签、前进后退按钮等,以及负责与其他进程协调
工作,同时提供存储功能GPU进程
:负责整个浏览器界面渲染
。Chrome刚开始发布的时候是没有GPU进程的,而使用GPU的初衷是为了实现3D CSS效果,只是后面网页、Chrome的UI界面都用GPU来绘制,这使GPU成为浏览器普遍的需求,最后Chrome在多进程架构上也引入了GPU进程网络进程
:负责发起和接受网络请求
,以前是作为模块运行在浏览器进程一时在面的,后面才独立出来,成为一个单独的进程插件进程
:主要是负责插件
的运行,因为插件可能崩溃,所以需要通过插件进程来隔离,以保证插件崩溃也不会对浏览器和页面造成影响渲染进程
:负责控制显示tab标签页
内的所有内容,核心任务是将HTML、CSS、JS转为用户可以与之交互的网页,排版引擎Blink和JS引擎V8都是运行在该进程中,默认情况下Chrome会为每个Tab标签页创建一个渲染进程
浏览器的渲染进程是多线程
的
GUI渲染线程
:负责渲染页面
,解析html和CSS、构建DOM树、CSSOM树、渲染树、和绘制页面,重绘重排也是在该线程执行- 当界面需要重绘回流时,该线程就会执行
- 当JS引擎执行时,GUI线程会被挂起(冻结),GUI更新会被保存在一个队列中等到
JS引擎空闲
时立即被执行。
JS引擎线程
:一个tab页中只有一个JS引擎线程
(单线程),负责解析和执行JS
。- 它GUI渲染进程不能同时执行,只能一个一个来,如果JS执行过长就会导致阻塞掉帧
计时器线程
:指setInterval
和setTimeout
,- 因为JS引擎是单线程的,所以如果处于阻塞状态,那么计时器就会不准了,所以需要单独的线程来负责计时器工作
- 当
JS引擎空闲
时才会去执行 - W3C规定要求setTimeout中低于4ms的时间间隔算为
4ms
- 不是由js引擎计数,阻塞线程状态就会影响记计时的
精度
异步http请求线程
:XMLHttpRequest
连接后浏览器开的一个线程,比如请求有回调函数,异步线程就会将回调函数加入事件队列,等待JS引擎空闲执行事件触发线程
:主要用来控制事件循环,- 比如JS执行遇到计时器,AJAX异步请求等,就会将异步任务添加到事件触发线程中,在对应事件触发时,就把事件添加到待
处理队列
的队尾,等JS引擎处理
- 比如JS执行遇到计时器,AJAX异步请求等,就会将异步任务添加到事件触发线程中,在对应事件触发时,就把事件添加到待
GUI渲染线程与JS引擎线程是
互斥的
多标签之间怎么通信
localStorage
:在一个标签页监听localStorage的变化,然后当另一个标签页修改的时候,可以通过监听获取新数据
window.addEventListener('storage', (e) => { ... })
WebSocket
:全双工通信
,因为websocket可以实现实时服务器推送,所以服务器就可以来当这个中介者。标签页通过向服务器发送数据,然后服务器再向其他标签推送转发postMessage
:
// 发送方
window.parent().pastMessage('发送的数据','http://接收的址')
// 接收方
window.addEventListener('message',(e)=>{ let data = e.data })
参考
从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
深入理解浏览器中的进程与线程