Achieve somewhat stable framerate with requestAnimationFrame?
Asked Answered
M

2

9

I am playing around with the requestAnimationFrame but I get very jerky animations in any other browser than Chrome.

I create an object like this:

var object = function() {

    var lastrender = (new Date()).getTime();
    var delta = 0;

    return {

        update: function() {
             //do updates using delta value in calculations.
        },

        loop: function() {
            var looptimestamp = (new Date()).getTime();
            delta = looptimestamp - lastrender;
            lastrender = looptimestamp;

            this.update();

            window.requestAnimationFrame(this.loop.bind(this));
        }
    };
}

Right now I am just drawing a single rectangle on a canvas element and moving it around. It is a very lightweight operation on the processor. This is running pretty smoothly in Chrome, and when I console log the delta value, it is almost consistant around ~17. However, if I do the same in Firefox or Safari I get the following delta values:

17-3-17-2-32-34-32-31-19-31-17-3-0-14-3-14-35-31-16-3-17-2 ... and so on

It looks as if the browser is not syncing with the display very nicely, and in all other cases than Chrome, one would get smoother animations using the old setTimeout method with 16ms as the target timeout.

Does anyone know, if it is possible to get smoother animations using requestAnimationFrame in browsers other than Chrome? Has anyone succeded in getting more stable delta values than the ones posted above in Firefox?

Molecular answered 15/5, 2013 at 9:19 Comment(8)
what kind of animation are you working on ? suggest to make a jsfiddle.Suspicious
How about testing with performance.now() rather than new Date().getTime()? I doubt that the resolution of the timer would be in the range of 2ms...Sutter
Nothing interesting at the moment, I have an app that moves quite a bit of div's around, and I'm looking into moving this sort of animation to a canvas element. But right now I am just trying to get a somewhat smooth animation running.Molecular
Did you look into CSS transitions? They use the GPU for rendering and they produce just about the smoothest effects i've seen in a browser so far. You can give them a whirl here: css3maker.com/css3-transition.htmlTheodore
you should actually provide the actual animations your are doing. it might not have anything to do with the loop per se, but rather how you are drawing and translating objects...Rakehell
Other browsers are extremely slow, and chrome is extremely fast. Anywhere your code could have improvements, browsers other than chrome are going to fail to optimize that code, and you will see it. *NOTE: this is a generic statement that will not always, but usually will, prove true.Diamagnet
Can you please provide a (possibly complete) fiddle that shows the problem in action?Coleorhiza
I think you omitted the problem code. Can you show the code in object.update(). You are probably causing a lot of reflows, which will kill performance. You can usually use the timeline in chrome devtools to find out what is causing the slowdown.Candlepower
O
4

The reason the smooth framerate of your animation decreases is because of the memory of your browser with regards to the canvas. I don't know the real details of the performance in browsers but firefox almost immediately has a framerate drop and in chrome the drop occurs some time later.

The real problem of the framerate drop is because of the memory occupied by the canvas element. Each time you draw something to the canvas that operation is saved to the path of the canvas. This path occupies more memory each time you draw something on the canvas. If you don't empty the path of the canvas you will have framerate drops. The canvas path can't be emptied by clearing the canvas with context.clearRect(x, y, w, h);, instead you have to reset the canvas path by beginning a new path with context.beginPath();. For example:

// function that draws you content or animation
function draw(){
    // start a new path/empty canvas path
    canvas.beginPath(); 

    // actual drawing of content or animation here 
}
Overcurious answered 25/5, 2014 at 18:37 Comment(0)
B
0

You might get smoother animation if you skip updates when delta < threshold, for example:

if (delta > 5) this.update();
Beaded answered 11/12, 2013 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.