setTimeout和setInterval在JS执行时会把任务加入到宏队列等待执行,根据运行机制特性,只有当JS全局执行栈空闲时才会执行宏队列的任务,那么动画代码就要等到前面的任务都完成才能执行。
requestAnimationFrame 浏览器会新开一个线程,会把每一帧中的所有绘制操作集中起来,根据浏览器的刷新间隔的回调流中完成绘制。
测试代码:
// 全局执行栈
console.log(0)
console.log(0)
console.log(0)
//该函数执行会加入宏队列
setTimeout(function(){ console.log(1);})
//浏览器单独开一个线程执行
requestAnimationFrame(function(){ console.log(2)});
var ul = document.getElementById("test");
var observer = new MutationObserver(function fun2(){
//该函数执行会进入微队列
console.log(3)
})
// 观察ul的子元素是否发生了变化,如果变化了,则运行fun2
observer.observe(ul,{
childList:true
})
ul.innerHTML = '<li>test</li>';
最后输出 0 0 0 3 2 1
总结:
JS执行顺序:全局执行栈 》 微队列 》 宏队列 根据我实际测试requestAnimationFrame的优先级: 微队列 > requestAnimationFrame > 宏队列