我们经常说浏览器是多进程的,js是单线程的,这句话怎么理解呢?那就通过下文一起来探索一下吧~
1. 进程、线程概念
进程。CPU资源分配的最小单位(能拥有资源和独立运行的最小单位,进程之间不会共享资源)线程。CPU调度的最小单位(线程是建立在进程基础上的一次程序运行单位,一个进程中可以有多个线程,多个线程共享进程中的资源)
举个很经典也很好理解的例子:进程好比工厂,线程好比工厂里的工人,工厂有自己的资源和空间,工厂里会有很多工人,工人没有自己的资源和空间,工厂的资源和空间可以被工厂的工人所共享
2. 对浏览器的基本认识
- 浏览器是
多进程的。能够有效避免单个页面崩溃影响整个浏览器;避免第三方插件崩溃影响整个浏览器;多进程充分利用多核优势;方便利用沙盒模型隔离插件等进程,提高浏览器稳定性;整体来看是利用空间换时间,牺牲内存 - 浏览器之所以能够运行,是因为系统给它分配了资源(CPU、内存)
- 浏览器每打开一个tab页,就相当于创建了一个独立的浏览器进程
3. 浏览器都包含哪些进程
3.1 浏览器进程(Browser进程)
- 浏览器的主进程,
只有一个 - 负责浏览器界面的呈现(放大、缩小、关闭等),与用户的交互(网址栏输入、前进、后退等)
- 负责管理各个页面,创建和销毁进程(如tab页的新建与关闭)
- 将页面内容(位图)写入到浏览器内存中,绘制到用户界面上
- 文件存储等功能
3.2 渲染进程(Render进程)
浏览器内核,内部是多线程的- 默认一个tab页面一个渲染进程,特殊情况除外
- 主要作用为
页面渲染、脚本执行、事件处理等
3.2.1 GUI渲染线程
- 负责浏览器界面渲染,解析HTML、CSS,构建DOM树和Render树,布局和绘制
- 当界面需要重绘(Repaint)或某种操作引发回流(Reflow)时,该线程就会执行
- 与js引擎互斥,当执行js引擎线程时,GUI会被挂起,当js引擎任务队列空闲时,才会继续执行GUI渲染
3.2.2 JS引擎线程
js内核,负责处理JavaScript脚本程序- js引擎线程负责解析JavaScript脚本,运行代码
- js引擎一直等待任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个js线程在运行程序
- 【注】JS引擎与GUI互斥,如果js执行时间过长,造成页面渲染不连贯,最终导致页面渲染加载阻塞
3.2.3 事件触发线程
- 用来控制事件循环(Even Loop)
- 当JS引擎执行如setTimeout时(也可来自浏览器内核的其他线程,如鼠标点击,Ajax异步请求等),会将对应的任务添加到事件线程中
- 当对应事件符合触发条件时被触发,该线程会把事件添加到待处理队列的队尾
- 【注】只有JS引擎空闲时,才会按队列依次处理事件
3.2.4 定时器触发线程
- setinterval,setTimeout所在线程
- 由于js引擎可能阻塞造成计时不准确,单独开启定时器触发进程来计时,计时完毕添加到事件队列,等待JS引擎空闲时执行
- w3c规定setTimeout中低于4ms的时间间隔为4ms
3.2.5 异步HTTP请求线程(IO线程)
- XMLHttpRequest连接后通过浏览器新开一个线程请求
- 检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调放入事件队列,等待JS引擎空闲时执行
3.3 GPU进程
最多可创建一个,用于3D绘制,也就是开启了GPU加速
3.4 网络进程
主要负责页面的网络资源加载,之前作为一个模块运行在浏览器进程里面,现在独立开来,成为一个单独的进程
3.5 插件进程
每种类型的插件只有一个进程,只有当插件运行时才会创建