在 debounce 函数中使用 requestAnimationFrame 是个好主意吗?
Posted
技术标签:
【中文标题】在 debounce 函数中使用 requestAnimationFrame 是个好主意吗?【英文标题】:Is it a good idea to use requestAnimationFrame within a debounce function? 【发布时间】: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
并节省创建更多函数范围
【参考方案1】:
这会奏效。
它有一个对您可能重要也可能不重要的警告:
如果页面当前不可见,则该页面上的动画可能会受到严重限制,因此它们不会经常更新,因此消耗的 CPU 资源很少。
所以如果你出于某种原因关心你正在去抖动的函数,你最好使用setTimeout(fn, 0)
否则,如果您将其用于动画,这是requestAnimationFrame
的预期用法
【讨论】:
这对我的特殊情况很有意义-我正在对resize
事件进行一些 DOM 交互,如果我的选项卡未处于活动状态,我可以接受该交互不是直到用户切换回我的标签为止。以上是关于在 debounce 函数中使用 requestAnimationFrame 是个好主意吗?的主要内容,如果未能解决你的问题,请参考以下文章