求大佬拯救我
相信很多人看过这段话:
浏览器内核是多线程的,其中一个常驻线程叫javascript引擎线程,负责执行js代码,还有一个常驻线程叫GUI渲染线程,负责页面渲染,dom重画等操作。javascript引擎是基于事件驱动单线程执行的,js线程一直在等待着任务列表中的任务到来,而js线程与gui渲染线程是互斥的,当js线程执行时,渲染线程呈挂起状态,只有当js线程空闲时渲染线程才会执行。
下面有我的三段测试代码:
document.querySelector('body').innerHTML = Math.random()
console.log(document.querySelector('body').innerHTML)
var time = new Date().valueOf()
while(new Date().valueOf() - time < 2000) {}
// console是最新的随机数,页面2秒后更新
document.querySelector('body').innerHTML = Math.random()
console.log(document.querySelector('body').innerHTML)
Promise.resolve().then(()=>{
var time = new Date().valueOf()
while(new Date().valueOf() - time < 2000) {}
})
// console是最新的随机数,页面2秒后更新
document.querySelector('body').innerHTML = Math.random()
console.log(document.querySelector('body').innerHTML)
setTimeout(()=>{
var time = new Date().valueOf()
while(new Date().valueOf() - time < 2000) {}
}, 1)
// console是最新的随机数,页面2秒后更新
document.querySelector('body').innerHTML = Math.random()
console.log(document.querySelector('body').innerHTML)
setTimeout(()=>{
var time = new Date().valueOf()
while(new Date().valueOf() - time < 2000) {}
}, 100)
// console是最新的随机数,页面立刻更新
我的问题是:
dom什么时候更新?
同步代码和微任务执行完更新?好像不是。
js线程空闲的时候更新?好像是,那么什么时候算是js线程空闲?
简单的讲一下吧,说深了可能是一个大长篇。
其实这个很好理解,推荐先学习一下
requestAnimationFrame
这个API其根本原因在于浏览器屏幕有一个相对稳定的刷新频率,理想情况是每秒60次。也就是 1000/60,大概16.66ms屏幕会刷新一次
根据浏览器的刷新屏幕,再对照上述代码 和 js线程 Gui线程理论 是不是马上就理解了呢
你的前三种情况,无论是同步还是微任务还是宏任务触发,因为都卡在了浏览器 绘制频率的时间内,后续都被js线程占有,停下了Gui绘制,所以结果是一样。 最后一种情况定时器的宏任务执行时间 足够浏览器屏幕更新大概五六次了,所以屏幕UI早就更新完毕了,后续才执行的 setTimeout宏任务