浏览器架构和事件循环
chrome浏览器架构
Chrome 采用多进程架构,其顶层存在一个 Browser process 用以协调浏览器的其它进程。
- Browser Process:
负责包括地址栏,书签栏,前进后退按钮等部分的工作;
负责处理浏览器的一些不可见的底层操作,比如网络请求和文件访问;
- Renderer Process:
- 负责一个 tab 内关于网页呈现的所有事情
- Plugin Process:
- 负责控制一个网页用到的所有插件,如 flash
- GPU Process
- 负责处理 GPU 相关的任务
由于一个tab标签页都有一个独立的渲染进程,所以一个tab异常崩溃后,其他tab不会受到影响。
一个渲染进程包括
- JS引擎线程
- HTTP请求线程
- 定时触发线程
- 事件触发线程
- GUI线程
浏览器JS异步执行原理
执行JS代码的线程只有一个,是浏览器提供的JS引擎线程,浏览器中还有
事件循环
js引擎解析代码时,遇到同步任务->放入执行栈直接执行,遇到异步任务(比如ajax),交给网络线程处理,完成后将对应回调放入异步任务队列,当执行栈清空时,循环检测异步任务队列,将异步队列中的回调放入执行栈中执行。
宏任务和微任务
Dom渲染会在微任务结束后,宏任务执行前
宏任务
# | 浏览器 | Node |
---|---|---|
I/O |
✅ | ✅ |
setTimeout |
✅ | ✅ |
setInterval |
✅ | ✅ |
setImmediate |
❌ | ✅ |
requestAnimationFrame |
✅ | ❌ |
微任务
# | 浏览器 | Node |
---|---|---|
process.nextTick |
❌ | ✅ |
MutationObserver |
✅ | ❌ |
Promise.then catch finally |
✅ | ✅ |
事件循环加入宏任务微任务
- Call Stack调用栈清空
- 清空当前微任务队列
- 尝试DOM渲染
- 执行event loop
- 取出任务队列里的一个宏任务,入栈执行
- 返回1
对于以下demo
1 | new Promise((r) => { |
Promise.prototype.then()
会隐式返回一个新 Promise
如果 Promise 的状态是 pending,那么 then
会在该 Promise 上注册一个回调,当其状态发生变化时,对应的回调将作为一个微任务被推入微任务队列
如果 Promise 的状态已经是 fulfilled 或 rejected,那么 then()
会立即创建一个微任务,将传入的对应的回调推入微任务队列
对于以下demo:
1 | console.log('start') |