【问题标题】:Is it a good idea to use requestAnimationFrame within a debounce function?在 debounce 函数中使用 requestAnimationFrame 是个好主意吗?
【发布时间】:2015-06-04 05:36:51
【问题描述】:

这是对我对requestAnimationFrame的理解的检查。我需要一个 debounce 函数,因为每次调整窗口大小时我都会进行一些 DOM 交互,并且我不想让浏览器过载。典型的 debounce 函数每个间隔只会调用一次传递的函数;区间通常是第二个参数。我假设对于很多 UI 工作,最佳间隔是不会使浏览器超载的最短时间。在我看来,这正是requestAnimationFrame 会做的事情:

var debounce = function (func, execAsap) {
   var timeout;

  return function debounced () {
    var obj = this, args = arguments;
    function delayed () {
      if (!execAsap)
        func.apply(obj, args);
      timeout = null; 
    };

    if (timeout)
      cancelAnimationFrame(timeout);
    else if (execAsap)
      func.apply(obj, args);

    timeout = requestAnimationFrame(delayed); 
  };
}

上面的代码是直接抄袭the above debounce link,但使用requestAnimationFrame而不是setTimeout。据我了解,这将尽快将传入的函数排队,但是任何传入速度快于浏览器处理能力的调用都将被丢弃。这应该会产生最顺畅的交互。我在正确的轨道上吗?还是我误会requestAnimationFrame

(当然,这只适用于现代浏览器,但对于 requestAnimationFrame 有一些简单的 polyfill,它只是回退到 setTimeout。)

【问题讨论】:

  • 如果是关于重绘,并且您想要一个流畅的动画,您希望 节流 而不是 去抖动。请重新阅读您链接的博客文章,看看有什么区别 - debounce 不是“每个间隔调用一次传递的函数”
  • @Bergi 谢谢你。我第一次考虑过这个问题,但我重新审视了它,并阅读了 Ben Alman 关于差异的注释benalman.com/projects/jquery-throttle-debounce-plugin,我认为你可能是对的 - 不过,我认为使用可以快速响应的快速浏览器,它最小化两者之间的差异。
  • 也在想同样的事情。很高兴我找到了这篇文章。添加要使用的上下文参数而不是var obj = this 是个好主意。这样人们就不必在调用之前使用bind 并节省创建更多函数范围

标签: javascript requestanimationframe debouncing


【解决方案1】:

这会奏效。

它有一个对您可能重要也可能不重要的警告:

如果页面当前不可见,则该页面上的动画可能会受到严重限制,因此它们不会经常更新,因此消耗的 CPU 资源很少。

所以如果你出于某种原因关心你正在去抖动的函数,你最好使用setTimeout(fn, 0)

否则,如果您将其用于动画,这是requestAnimationFrame 的预期用法

【讨论】:

  • 这对我的特殊情况很有意义-我正在对 resize 事件进行一些 DOM 交互,如果我的选项卡未处于活动状态,我可以接受该交互不是直到用户切换回我的标签为止。
猜你喜欢
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 2017-09-16
相关资源
最近更新 更多