admin管理员组

文章数量:1420128

I've e across this example on MDN that uses requestAnimationFrame instead of setTimeout:

// Reference: /

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;
});

And it got me thinking whether we can use requestAnimationFrame instead of setTimeout(fn, 0) and if there is any advantage to this? I've googled and it seems that all parisons are done in the context of animations, but what about unrelated functionality - like debounce/throttle or simply if you need to run code after repaint?

I've e across this example on MDN that uses requestAnimationFrame instead of setTimeout:

// Reference: http://www.html5rocks./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;
});

And it got me thinking whether we can use requestAnimationFrame instead of setTimeout(fn, 0) and if there is any advantage to this? I've googled and it seems that all parisons are done in the context of animations, but what about unrelated functionality - like debounce/throttle or simply if you need to run code after repaint?

Share Improve this question edited Oct 27, 2016 at 6:48 Shayan Ghosh 8926 silver badges14 bronze badges asked Oct 27, 2016 at 6:47 Max KoretskyiMax Koretskyi 106k68 gold badges353 silver badges516 bronze badges 2
  • SetTimeout registers an event to necessary tick. So if you have a large task before it which takes say 5 ticks, your function will execute later. This can give some issues if you have same function running at every tick. requestAnimationFrame will skip all delayed tasks and processes based on current time. So in this scenario, only last task will run, You can check following post: stackoverflow./questions/13935262/… – Rajesh Commented Oct 27, 2016 at 6:56
  • RequestAnimationFrame's advantage is that its designed to fire during your monitors next draw sync. IOW Its designed to prevent flicker / tearing. Because of this setTimeout's advantage in HTML5 is it can fire every 4ms, so is faster. But I beleive the fastest is Postmessage. – Keith Commented Oct 27, 2016 at 7:07
Add a ment  | 

3 Answers 3

Reset to default 2

RequestAnimationFrame is good if you want to make sure you don't do unnecessary work because you changed something two times between 2 frame updates.

In itself, the requestAnimationFrame is not useful for anything other than animation, because it can only wait 16.666 milliseconds (if there's no lag), thus you need to chain multiple together. But if you pair it with setTimeout, then you will be able to wait a sepcific amount of milliseconds and also make sure you draw everything in the correct time.

requestAnimationFrame is called at the time when the browser is in the repaint step. So in theory it should avoid flickering/jittering if you try to sync properties of elements (like the position) with the scroll position.

setTimeout will be called after a minimum of n milliseconds, so you callback might be called multiple times before the next repaint and you will wast CPU usage, or multiple successive repaints happen without that the callback is called which will result into flickering/jittering if you try to sync properties of the elements with the scroll position.

Apart from above answers,

When using requestAnimationFrame your animations will only run when the tab (or window) is visible to the user. This means less CPU, GPU and memory usage, hence Battery Friendly. This is especially important for mobile devices that typically have a relatively short battery life.

But for smooth animations we have to take care that our frame rendering happens in less than 16ms, so callback should be as small as possible for 60 fps animations.

本文标签: