【问题标题】:Is there any advantage to using requestAnimationFrame instead of setTimeout for debounce/throttle使用 requestAnimationFrame 而不是 setTimeout 进行去抖动/节流有什么好处吗
【发布时间】:2017-03-09 17:52:07
【问题描述】:

我在 MDN 上遇到过这个使用 requestAnimationFrame 而不是 setTimeout 的示例:

// Reference: http://www.html5rocks.com/en/tutorials/speed/animations/

var last_known_scroll_position = 0;
var ticking = false;

function doSomething(scroll_pos) {
  // do something with the scroll position
}

window.addEventListener('scroll', function(e) {
  last_known_scroll_position = window.scrollY;
  if (!ticking) {
    window.requestAnimationFrame(function() {
      doSomething(last_known_scroll_position);
      ticking = false;
    });
  }
  ticking = true;
});

这让我想到我们是否可以使用requestAnimationFrame 而不是setTimeout(fn, 0),这是否有任何优势?我用谷歌搜索过,似乎所有的比较都是在动画的上下文中完成的,但是不相关的功能呢——比如去抖动/节流,或者只是如果你需要在重绘后运行代码?

【问题讨论】:

  • SetTimeout 将事件注册到必要的滴答声。因此,如果您之前有一个需要 5 个滴答的大型任务,您的函数将稍后执行。如果您在每个刻度上运行相同的功能,这可能会产生一些问题。 requestAnimationFrame 将根据当前时间跳过所有延迟的任务和进程。所以在这种情况下,只有最后一个任务会运行,您可以查看以下帖子:stackoverflow.com/questions/13935262/…
  • RequestAnimationFrame 的优势在于它被设计为在您的监视器下一次绘制同步期间触发。 IOW 它旨在防止闪烁/撕裂。因为这个 setTimeout 在 HTML5 中的优势是它可以每 4 毫秒触发一次,所以速度更快。但我相信最快的是 Postmessage。

标签: javascript requestanimationframe


【解决方案1】:

RequestAnimationFrame 很好,如果您想确保不做不必要的工作,因为您在 2 帧更新之间更改了两次。

就其本身而言,requestAnimationFrame 对动画以外的任何东西都没有用,因为它只能等待 16.666 毫秒(如果没有延迟),因此您需要将多个链接在一起。但是如果你将它与 setTimeout 配对,那么你将能够等待特定的毫秒数,并确保你在正确的时间绘制所有内容。

【讨论】:

    【解决方案2】:

    requestAnimationFrame 在浏览器处于重绘步骤时调用。因此,理论上,如果您尝试将元素的属性(如位置)与滚动位置同步,它应该避免闪烁/抖动。

    setTimeout 将在至少 n 毫秒后被调用,因此您的回调可能会在下一次重绘之前被多次调用,您将浪费 CPU 使用率,或者在没有调用回调的情况下发生多次连续重绘,这将如果您尝试将元素的属性与滚动位置同步,则会导致闪烁/抖动。

    【讨论】:

      【解决方案3】:

      除了以上答案,

      使用 requestAnimationFrame 时,您的动画只会在标签(或窗口)对用户可见时运行。这意味着更少的 CPU、GPU 和内存使用,因此电池友好。这对于电池寿命通常相对较短的移动设备尤其重要。

      但对于流畅的动画,我们必须注意帧渲染的时间少于 16 毫秒,因此对于 60 fps 的动画,回调应该尽可能小。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-09
        • 2018-02-16
        • 1970-01-01
        • 2016-12-07
        • 2015-07-25
        • 2019-11-11
        • 2011-12-09
        • 2012-05-18
        相关资源
        最近更新 更多