浏览器是多进程的,而主进程只有一个,负责浏览器界面的显示,与用户交互,负责各个页面的管理,创建和销毁其他进程,其次,第三方插件进程,只有使用该插件是才给他创建一个进程,每个页面也会开一个进程,重点是要说一下浏览器的渲染进程。
浏览器的渲染进程,主要包括页面的渲染,JS的执行,事件的循环。浏览器的渲染进程是多线程的:
1、GUI渲染线程
- 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
- 当界面需要重绘或引发回流时,该线程就会执行
- GUI渲染线程与JS引擎线程是互斥的。
2、JS引擎线程
- 也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)
- JS引擎线程负责解析Javascript脚本,运行代码。
- JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序
3、事件触发线程
- 归属于浏览器而不是JS引擎,用来控制事件循环
- 当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中
- 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理
- 注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)
4、定时触发器线程
- 传说中的
setInternal与setTimeout所在线程 - 浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)
- 因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)
- 注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
5、异步http请求线程
- 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求
- 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。
更详细的讲解,请移步:从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
javascript 的运行机制
这个时候,浏览器页面初次渲染完成,我们来看JS引擎的一些运行机制。JS引擎是单线程,为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。
所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
这里就直接引用一张图片来协助理解:(参考自Philip Roberts的演讲《Help, I’m stuck in an event-loop》)
宏任务与微任务
宏任务:setTimeout, setInterval, setImmediate, I/O
微任务:原生Promise(有些实现的promise将then方法放到了宏任务中),Object.observe(已废弃), MutationObserver, MessageChannel
当主线程执行完毕,如果微任务队列中有微任务,则会先进入执行栈,当微任务队列没有任务时,才会执行宏任务的队列。
console.log(1);
setTimeout(function(){
console.log(2);
Promise.resolve(1).then(function(){
console.log('promise')
})
})
setTimeout(function(){
console.log(3);
})
在浏览器中执行:
1
73084
2
promise
3
Node环境下的Event Loop
把上面的代码在node中执行,你会看到不一样的结果:
1
2
promise
3这是为什么呢?先了解下node.js的运行机制:
(1)V8引擎解析JavaScript脚本。
(2)解析后的代码,调用Node API。
(3)将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。
(4)V8引擎再将结果返回给用户。
Event loop的事件处理机制如何运作?
分为5个阶段:
详解请阅读:Nodejs 解读event loop的事件处理机制
参考文章:
javascript 运行机制详解:再谈Event Loop