对于debounce / throttle

时间:2016-10-27 06:47:12

标签: javascript requestanimationframe

我在使用requestAnimationFrame代替setTimeout的MDN上遇到了这个示例:

// 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),如果有任何优势呢?我用谷歌搜索过,似乎所有的比较都是在动画的背景下完成的,但是不相关的功能呢 - 比如debounce / throttle或者只是你需要在重绘后运行代码?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

在浏览器处于重绘步骤时调用

requestAnimationFrame。因此,理论上,如果您尝试将元素的属性(如位置)与滚动位置同步,则应避免闪烁/抖动。

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

答案 2 :(得分:1)

除上述答案外,

使用requestAnimationFrame时,只有当用户可以看到选项卡(或窗口)时,才会运行动画。这意味着更少的CPU,GPU和内存使用,因此电池友好。这对于通常电池寿命相对较短的移动设备尤其重要。

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