前端

前端宏任务、微任务、Dom 渲染的顺序

2021-08-31  本文已影响0人  涅槃快乐是金

1.浏览器包含多个进程

2.渲染进程包含了多个线程:

3. 为什么 JS 引擎线程和 GUI 渲染线程是互斥的?

JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面,那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置 GUI 渲染线程与 JS 引擎为互斥的关系,当 JS 引擎执行时 GUI 线程会被挂起,GUI 更新则会被保存在一个队列中等到 JS 引擎线程空闲时立即被执行。

4. 为什么 JS 会阻塞页面加载?

从上面的互斥关系可以推导出,JS 如果执行时间过长就会阻塞页面。譬如,假设 JS 引擎正在进行巨量的计算,此时就算 GUI 有更新,也会被保存到队列中,等待 JS 引擎空闲后执行。然后,由于巨量计算,所以 JS 引擎很可能很久很久后才能空闲,自然会感觉到巨卡无比。所以,要尽量避免 JS 执行时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

5. JS 引擎线程和 GUI 渲染线程是互斥的,那先后顺序呢?

把下面三段代码放到浏览器的控制台执行:

document.body.style = "background:black";
document.body.style = "background:red";
document.body.style = "background:blue";
document.body.style = "background:grey";
document.body.style = "background:blue";
console.log(1);
Promise.resolve().then(function () {
  console.log(2);
  document.body.style = "background:black";
});
console.log(3);
document.body.style = "background:blue";
setTimeout(function () {
  document.body.style = "background:black";
}, 0);

总结:

1.先把Call Stack清空
2.然后执行当前的微任务
3.接下来DOM渲染
微任务在dom渲染之前执行,宏任务在dom渲染之后执行。

上一篇 下一篇

猜你喜欢

热点阅读