将requestAnimationFrame用于非动画目的有什么好处? [英] Any advantages of using requestAnimationFrame for non-animation purposes?

查看:103
本文介绍了将requestAnimationFrame用于非动画目的有什么好处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我睡着了计时器函数,该函数递归调用requestAnimationFrame并在时间用完后返回promise.使用requestAnimationFrame可以为我带来任何性能优势,还是我应该只使用setTimeout?我知道requestAnimationFrame在非常短/快速的等待时间(又称动画帧)中具有更好的性能,但是对于接近或超过一秒的等待时间,有什么区别吗?

I made a "sleep" timer function that recursively calls requestAnimationFrame and returns a promise after the time runs out. Is there any performance advantage in me using requestAnimationFrame for this or should I have just used setTimeout? I know requestAnimationFrame has better performance for very short/quick wait times (aka animation frames) but for wait times near or more than a second does it make a difference?

var sleep = (time) =>{
  var timer = (t, s, d, r)=>{
    if(t - s > d){
      r("done")
    } else {
      requestAnimationFrame((newT)=>{ timer(newT, s, d, r)})
    }
  }
  return new Promise((r)=>{
    requestAnimationFrame((t)=>{timer(t, t, time, r)})
  })
}

(async ()=>{
  var message = document.getElementById("message")
  while(message){
    message.innerText = "Get"
    await sleep(1000)
    message.innerText = message.innerText + " Ready"
    await sleep(1000)
    message.innerText = message.innerText + " To"
    await sleep(1000)
    message.innerText = message.innerText + " Wait"
    await sleep(1000)
  }
})()

<p style="text-align:center; font-size:20px;" id="message"></p>

推荐答案

requestAnimationFrame 不是只是计时方法,它也请求 动画帧.

requestAnimationFrame is not just a timing method, as its name says, it also does request an animation frame.

在浏览器中,事件循环处理模型首先执行常规任务,然后在浏览器中认为应该更新渲染,它调用了此处理模型的一个特殊部分,该部分

In a browser, the event loop processing model does first execute normal tasks, and then, when the browser thinks it should update the rendering, it calls a special part of this processing model which will well, update the rendering.

在大多数事件循环迭代中,进入处理模型的此可选部分所需的条件均未得到满足,因此不进行渲染,这很好,因为渲染成本很高.

In most event loop iterations, the conditions required to enter this optional part of the processing model are not met, and thus, no rendering is done, which is great because rendering is costly.

即使规范留给实施者选择他们将用来决定何时更新渲染的试探法的选择,但大多数人仍将监视器的刷新率用作基本频率.
除了此监视器的刷新事件外,它们仅更新标记为需要更新的文档的呈现.
大多数情况下,不需要重新渲染网页,只有在运行动画或用户与之交互时,它们才会将文档标记为需要重新渲染.

Even though the specs leave to implementers the choice of what heuristics they'll use to decide when they should update the rendering, most will use the monitor's refresh-rate as base frequency.
In addition to this monitor's refresh event, they only update the rendering of the Documents that they marked as needing an update.
Most of the time, a web page doesn't need to be re-rendered, and only when an animation is running, or when the user did interact with it, they'll mark the document as being in need of a re-render.

requestAnimationFrame 是一个让我们的Web开发人员在此更新渲染子过程中进行钩挂的工具,它使我们仅在渲染将要发生时才进行绘制,但它也具有以下副作用:将网页标记为动画",从而强制浏览器执行完整的更新渲染"步骤,即使可能不需要.

requestAnimationFrame is a tool for us web-devs to hook in this update the rendering sub-process, allowing us to draw things only when the rendering will happen, but it also has the side effect of marking the web page as animated, and thus forces browser to execute the full update the rendering steps even though it might not have been needed.

例如,使用Chrome的Performance开发工具,您可以在下面的代码段中看到,一个简单的空rAF循环会导致 Composite Layer 操作在每次屏幕刷新时都被触发,而这只会发生当鼠标以其他方式移动时,以及仅仅因为鼠标内部移动调用了rAF).

For instance, using Chrome's Performance dev tools, you can see in below snippet that a simple empty rAF loop will cause the Composite Layer operation to get triggered every screen-refresh, while it would happen only when the mouse moves otherwise, and just because mouse-move internally calls rAF).

const input = document.querySelector("input");
input.oninput = (evt) => {
  rAFLoop();
};
function rAFLoop() {
  if( input.checked ) {
    requestAnimationFrame( rAFLoop );
  }
}

<label><input type="checkbox" id="inp">activate rAF loop</label>

因此,尽管 requestAnimationFrame 是用于视觉动画的出色工具,但它也带有责任感,对于您而言,您是在滥用它.

So while requestAnimationFrame is a great tool for visual animations, it also comes with responsibilities, and in your case, you are misusing it.

使用简单的 setTimeout 是可行的方法,不仅与渲染过程没有任何关系,而且甚至可以使浏览器进入 idle 如果没有其他反应,则让您的计算机执行其他任务或保存树.

Using a simple setTimeout is the way to go, not only it won't have anything to do with the rendering process, but it can even let the browser go idle if nothing else happens, letting your computer do other tasks, or saving trees.

const sleep = (ms) =>
  new Promise( (res) =>
    setTimeout( () => res(), ms )
  );
(async ()=>{
  var message = document.getElementById("message")
  while(message){
    message.innerText = "Get"
    await sleep(1000)
    message.innerText = message.innerText + " Ready"
    await sleep(1000)
    message.innerText = message.innerText + " To"
    await sleep(1000)
    message.innerText = message.innerText + " Wait"
    await sleep(1000)
  }
})()

<p style="text-align:center; font-size:20px;" id="message"></p>

这篇关于将requestAnimationFrame用于非动画目的有什么好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆