How to solve different FPS in requestAnimationFrame on different browsers?
The common thing to do is to create a deltaTime (dt) variable which is then be used as a parameter for every animation/update cycle.
Code is only for visualizing the problem/solution.
// ...timer: function(){ var now = new Date().getTime(); // get current time this.controls.dt = now - this.controls.time; // calculate time since last call this.controls.time = now; // update the current application time this.controls.frame++; // also we have a new frame return this.controls.dt ;}
for any call to the render function you then pass dt
// we call the update function with every request frameupdate: function(){ var dt = this.timer(); _.each(this.activeViews, function(item){ item.update(dt); }); // this is underscore.js syntax}
item.update(dt) looks like that
//...var x = this.position.get(x);x = x + (10*dt); // meaning: x increases 10 units every ms.this.position.x = x;
As far as I know there's no way to really fix this, other than making your code less resource intensive.
Chrome seems to be the fastest browser, but usually FF is not far behind, but IE is still slow. Depending on the rendering methods, canvas, svg or webGL, it's also very dependent on your local hardware as it uses the clientside for most things, and complicated webGL renderings need a powerful GPU to achieve good framerates.
There are ways to measure the framerate on the fly, and change your animations accordingly.
Here's a very simple example that measures framerate.
function step(timestamp) { var time2 = new Date; var fps = 1000 / (time2 - time); time = time2; document.getElementById('test').innerHTML = fps; window.requestAnimationFrame(step);}var time = new Date(), i = 0;window.requestAnimationFrame(step);
<div id="test"></div>
This is just an instant measure that's not that accurate, you'd probably want something that measures over some time to get a more correct framerate for the browser being used.
Also note the timestamp
argument, which in requestAnimationFrame
is high-res timestamp with a minimal precision of 1 milliseconds, that can also be used to deterine the speed of the animation, and any browser lag.
On some browsers requestAnimationFrame works something like
setTimeout(callback, 1000 / (16 + N)
where N is time required for your code to execute. Which means it caps your FPS at 62Hz but if your code works slowly, it will cap at something way lower. It basically tries to make a 16ms gap between every gap. Of course, this is not true for all browsers and will probably change in the future anyway but it still may give you an idea how it works.
Even if it was implemented the same in every browser, there are many factors which affect the performance of your code and etc. You can never be sure your code will be running at a constant frequency.