Call time of RequestAnimationFrame changes depending on canvas size

In my application, I have a canvas whose CSS size (CSS, not html) is updated based on the size of the window.

I have a main gameplayLoop that looks like this:

run = function(){



    frameTime = timerInit();




My requestAnimFrame function is from Paul Irish:

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);


Basically the problem is that the timer I am registering, which measures the time between the call to requestAnimFrame and the call to the efficient function, changes completely. If my browser is in full screen I get 50/60 ms, and if I have a small window I can get something like 10 ms.

Since the call to requestAnimFrame has to constantly call the function at 60fps (which is roughly like 30ms I guess), I shouldn't have that result since between creating the timer and checking it, other than requestAnimFrame

I also have some repetitive micro-freezes (less than a second) that happen like every 2/3 of a second. But the timer doesn't detect any change in time (for example, even the javascript time counter is blocked)

My timer functions are similar to this, but it doesn't matter here.

timerInit = function()
    return new Date();

timerDiff = function(datePrev)
    return new Date().getTime() - datePrev.getTime();



source to share

2 answers

Well, the standard basically says it requestAnimationFrame

will "do whatever it takes" to operate at a "consistent" frame rate. This does not guarantee 60 frames per second; he simply claims that he will animate as fast as he can.

My experience with this so far has been as lackluster as yours. I ended up going back to setTimeout

. It runs at roughly the same speed and graphical updates are accurate and clock-free as is the case with requestAnimationFrame

. Of course it wasn't 60fps, but at least you could tell what's going on.

I'm sure the performance will only improve as the browser developers optimize the new feature, but for now let's move on to timeouts


Edit: I would like to remind people that this was answered a year ago and the time has changed :)



"So basically the problem is that the timer I'm registering, which measures the time between the call to requestAnimFrame and the call to the efficient function, changes completely ..."

Of course this is why you need to measure it and BASED ON THE TRUE TIME DIFFERENCE, you calculate your next frame.

Let's say you want to animate the "left" property of a css div from 0px to 120px in 1 second at 60 frames per second.

  • using setTimeout because you are setting the number of frames you know how much you should increase the "left" property: 120px / 60frames = 2px / frame

  • using requestAnimationFrame you have no idea when the next frame will happen until it does; then you measure the time difference between this and the previous frame and you calculate the value you should increase the "css" left value "; if the frame happens after 500ms the distance increment = (120px * 500ms) / 1000ms = 60px; the ideea is that at the start of the animation you cannot have a fixed setpoint to increase with each frame, you need to calculate it dynamically based on the time difference

Thus, even if the animation is not rendered at 60fps, if frames are skipped, every frame that is not skipped will display the exact updated situation.

You need to play around a bit to decide when the animation should end.



All Articles