线程和进程
进程和线程的概念可以这样理解:
进程是一个工厂,工厂有它的独立资源--工厂之间相互独立--线程是工厂中的工人,多个工人协作完成任务--工厂内有一个或多个工人--工人之间共享空间
工厂有多个工人,就相当于一个进程可以有多个线程,而且线程共享进程的空间。
进程是cpu
资源分配的最小单位(是能拥有资源和独立运行的最小单位,系统会给它分配内存)
线程是cpu
调试的最小单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程。核心还是属于一个进程。)
浏览器是多进程的
浏览器是多进程的,每打开一个tab
页,就相当于创建了一个独立的浏览器进程。
浏览器包含的进程:
Browser
进程:浏览器的主进程(负责协调,主控),只有一个,作用有:
负责浏览器的界面显示,与用户交互,如前进,后退等
负责各个页面的管理,创建和销毁其它进程
将
Rendered
进程得到的内存中的Bitmap
,绘制到用户界面上网络资源的管理,下载
第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建。
GPU
进程:最多一个,用于3D
绘制等。
浏览器渲染进程(浏览器内核)(Render
进程,内部是多线程的):默认每个Tab
页面一个进程,互不影响。主要作用为:
页面渲染,脚本执行,事件处理等
在浏览器中打开一个网页相当于新起了一个进程(进程内有自己的多线程)
浏览器多进程的优势
避免单个
page crash
影响整个浏览器避免第三方插件
crash
影响整个浏览器多进程充分利用多核优势
方便使用沙盒模型隔离插件等进程,提高浏览器稳定性
简单理解就是:如果浏览器是单进程的,某个Tab
页崩溃了,就影响了整个浏览器,体验就会很差。同理如果是单进程的,插件崩溃了也会影响整个浏览器;
当然,内存等资源消耗也会更大,像空间换时间一样。
重点是浏览器内核(渲染进程)
对于普通的前端操作来说,最重要的渲染进程:页面的渲染,js
的执行,事件的循环等都在这个进程内执行;
浏览器是多进程的,浏览器的渲染进程是多线程的;
GUI
渲染线程
负责渲染浏览器界面,解析
HTML
,CSS
,构建DOM
树和RenderObject
树,布局和绘制等。当界面需要重绘或由于某种操作引发回流时,该线程就会执行。
注意,
GUI
渲染线程与JS
引擎线程是互斥的,当JS
引擎执行时GUI
线程会被挂起(相当于冻结了),GUI
更新会被保存在一个队列中等到JS
引擎空闲时立即被执行。
JS
引擎线程
也称为
JS
内核,负责处理JavaScript
脚本程序。(例如V8
引擎)。JS
引擎线程负责解析JavaScript
脚本,运行代码。JS
引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab
页(render
进程)中无论什么时候都只有一个JS
线程在运行JS
程序。同样注意,
GUI
渲染线程与JS
引擎线程是互斥的,所以如果JS
执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
事件触发线程
归属于浏览器而不是
JS
引擎,用来控制事件循环(可以理解成JS
引擎自己都忙不过来,需要浏览器另开线程协助)。当
JS
引擎执行代码块如setTimeout
时(也可来自浏览器内核的其它线程,如鼠标点击,AJAX
异步请求等),会将对应任务添加到事件线程中。当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待
JS
引擎的处理。注意,由于
JS
的单线程关系,所以这些待处理队列中的事件都得排队等待JS
引擎处理(当JS
引擎空闲时才会去执行)。
定时触发器线程
传说中的
setTimeout
和setInterval
所在的线程浏览器定时计数器并不是由
JavaScript
引擎计数的,(因为JavaScript
引擎是单线程的,如果处于阻塞线程状态就会影响计时的准确)因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待
JS
引擎空闲后执行)注意,
W3C
在HTML
标准中规定,规定要求setTimeout
中低于4ms
的时间间隔算为4ms
。
异步http
请求线程
在
XMLHttpRequest
在连接后是通过浏览器新型一个线程请求将检测到状态变更时&#x