js执行的比dom渲染快很多,执行完一定的js才在页面渲染一次dom,UI渲染是宏任务

发布时间 2023-11-11 12:51:25作者: 龙陌

假设HTML有一个按钮id为btn,经过以下操作最终会变成什么颜色?

document.getElementById('btn').style = 'background: blue';
document.getElementById('btn').style = 'background: red';
Promise.resolve().then(() => {
document.getElementById('btn').style = 'background: black';
})

A
由blue变成red再变成black
B
颜色不会发生改变
C
red
D
black

正确答案:D

官方解析:
首先明确UI渲染是宏任务,而按照事件循环的模型,先执行的是整体的主干代码,这期间style频繁变化但是还没有被渲染所以不会有颜色的变化,
同时因为有个微任务也就是promise回调函数,最终改变了style为black,之后才执行的UI渲染,也就是最后被改变的颜色了。

JS执行会阻塞渲染,是因为 js 有可能影响dom的解析,比如在 js 里面新增 dom 等这些操作。
而 dom 的渲染 是需要等js, css都解析完成后才进行的,所有代码都执行完之后,颜色就是黑色,不存在颜色变化的情况。

可以理解为js执行的比dom渲染快很多,执行一定的js才在页面渲染一次dom,

并且要考虑优化: 要是执行一行js就渲染更新一次页面的dom,那浏览器不是会累死

首先 js 是单线程,前两个同步代码执行完后,会产生两个 UI 渲染任务到交互消息队列,然后执行下面微任务代码,执行完后又产生一个 UI 渲染为黑色的任务到交互消息队列末尾,主线程到此执行结束,然后微消息队列为空,从交互队列中以此取任务,最后执行为黑色

关于JS阻塞DOM渲染,推荐看一下这个文章https://juejin.cn/post/6844903497599549453