花若 发表于 2023-7-21 14:23:44

chrome事件循环的自问自答

chrome事件循环的自问自答

目录


[*]1. 宏任务有哪些?
[*]2. 微任务有哪些?
[*]3. dom渲染是事件循环的一部分么?
[*]4. requestAnimationFrame的回调是宏任务还是微任务?
[*]5. requestIdleCallback的回调是宏任务还是微任务?
[*]6. 事件循环图例
1. 宏任务有哪些?


[*]事件回调 (js调用的 click box.click() )
[*]XHR或网络请求回调
[*]定时器的回调
[*]I/O回调
[*]history相关回调
[*]MessageChannel的message回调
在合适时机,这些宏任务会被推入宏任务队列;每一次事件循环会从宏任务队列中取一个任务执行。
history.back回调:
<button id='box'>forward</button>
<button id='box2'>back</button>MessageChannel的message回调
<button id='<button id='btn'>btn</button>'><button id='btn'>btn</button></button>I/O回调
2. 微任务有哪些?

MutationObserver的回调、Promise的then catch finally回调、queueMicrotask.
在合适时机,这些微任务会被推入微任务队列;每一次事件循环会从微任务队列中取所有任务并执行。
Promise和queueMicrotask不支持IE, MutationObserver支持IE11;
MutationObserver例子:
下面的代码中box.textContent = 1的位置不同,代码的执行顺序就不同以验证MutationObserver为微任务。
0以下是使用`queueMicrotask`方法手动添加微任务的例子,可以不会对更高优先级的代码运行造成干扰。
03. dom渲染是事件循环的一部分么?

从规范的角度来看,DOM渲染是事件循环的一部分,可以将其视为一种渲染任务。
如果宏任务或者微任务中发生了dom修改,因为一个渲染帧的时间可能远大于事件循环周期,所以不一定在本次事件循环会执行渲染任务。
0下图是上面的代码的执行流程,两个setTimeout的回调执行代表两次事件循环,在其后面出现了一个新的Task,仅执行了一次布局(layout)和绘制(paint);

4. requestAnimationFrame的回调是宏任务还是微任务?

requestAnimationFrame的回调函数会在浏览器在下一帧渲染之前执行,既不是宏任务,也不是微任务, 从规范上看是事件循环的一部分,从下图可以看到一个task下包含了requestAnimationFrame,layout paint, 可将其归类于渲染任务的一个可选步骤。
0上述代码中添加了两个requestAnimationFrame,可以看到两者在一个Task内顺序执行;并且回调中的微任务也在这个Task内执行;

5. requestIdleCallback的回调是宏任务还是微任务?

requestIdleCallback是事件循环的一部分,从图中可以看到,requestIdleCallback的回调是一个特殊的任务,这个函数的回调会在浏览器空闲时期被调用,所以不是每次循环都会执行该任务。
<button id='<button id='btn'>btn</button>'><button id='btn'>btn</button></button>
该任务的优先级比较低,多个平行声明的requestIdleCallback会拆开成单一的task, 两个连续task之间甚至会被内部的setTimeout插足。
for (let i = 0; i < 10; i++) {
requestIdleCallback(() => {
    console.log('idle', Date.now() - a)
    setTimeout(()=>{
      console.log(12121)
    })
})
}
6. 事件循环图例



来源:https://www.cnblogs.com/walkermag/p/17570671.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: chrome事件循环的自问自答