[英]Request animation frame called constantly
试图理解RequestAnimationFrame及其内部工作原理。
浏览器有一个主线程,它是一个事件循环。 事件循环可以填充各种异步事件,例如用户交互,定时器被触发,网络调用完成以及事件触发布局和绘制,例如输入或JS。
因此,当JS函数使DOM的布局无效或导致重新绘制时,浏览器的主线程重新绘制需要更新的图层,合成器线程将更新的纹理上传到GPU,最终合成发生,并将生成的图像显示在屏幕上。
所以,我的印象是浏览器只在实际需要时执行绘制。 如果您在静态页面上的Chrome开发工具时间轴上捕获事件而没有任何事情发生,则绝对不会捕获任何事件(没有布局,没有绘制,也没有触发动画帧)。 说得通。
但是,然后在控制台上运行以下代码,
function onBeforeNextRepaint() {
requestAnimationFrame(onBeforeNextRepaint);
console.log('About to paint ...');
}
onBeforeNextRepaint();
现在,您再次捕获时间轴事件,并注意到“动画帧触发”事件,并且您的控制台将使用“关于绘制...”进行记录。
根据MDN ,
Window.requestAnimationFrame()方法告诉浏览器您希望执行动画并请求浏览器调用指定的函数以在下次重绘之前更新动画。
这意味着浏览器不断绘画,因此调用我的函数在每次重绘之前记录消息。 我猜测浏览器维护一个调度程序,使绘制调用的速率与屏幕的刷新率相匹配。
现在我的困惑在于以下几点:
以下博客文章真的帮助我理解了整个过程的运作方式。
从中:
本质上,整个事件循环函数可以用这段代码来说明:
while (eventLoop.waitForTask()) {
const taskQueue = eventLoop.selectTaskQueue()
if (taskQueue.hasNextTask()) {
taskQueue.processNextTask()
}
const microtaskQueue = eventLoop.microTaskQueue
while (microtaskQueue.hasNextMicrotask()) {
microtaskQueue.processNextMicrotask()
}
if (shouldRender()) {
applyScrollResizeAndCSS()
runAnimationFrames()
render()
}
}
并描绘如下:
我认为你误解了MDN给出的描述。 让我分解一下。
Window.requestAnimationFrame()方法告诉浏览器您希望执行动画
这意味着它将告诉浏览器您希望预先形成需要重新绘制的动画。 但要做到这一点,我们将需要运行一些代码。
并请求浏览器调用指定的函数以在下次重绘之前更新动画。
这意味着在动画需要的下一次重绘之前,调用我的回调函数。
requestAnimationFrame
不是绘制事件回调,而是在浏览器现在必须执行的下一个绘制之前触发回调的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.