I want a constant requestAnimationFrame
frame rate. So we have this:
var stop = false;
var frameCount = 0;
var fps, fpsInterval, startTime, now, then, elapsed;
startAnimating(30);
function startAnimating(fps) {
fpsInterval = 1000 / fps;
then = window.performance.now();
startTime = then;
console.log(startTime);
animate();
}
function animate(newtime) {
// stop
if (stop) {
return;
}
// request another frame
requestAnimationFrame(animate);
// calc elapsed time since last loop
now = newtime;
elapsed = now - then;
// if enough time has elapsed, draw the next frame
if (elapsed > fpsInterval) {
// Get ready for next frame by setting then=now, but...
// Also, adjust for fpsInterval not being multiple of 16.67
then = now - (elapsed % fpsInterval);
// draw stuff here
// TESTING...Report #seconds since start and achieved fps.
var sinceStart = now - startTime;
var currentFps = Math.round(1000 / (sinceStart / frameCount) * 100) / 100;
console.log(currentFps " fps.");
}
}
But the issue is if you loss your focus on the page and minimize your browser wait seconds and come back to the window again the frame rate drops suddenly. But we want a constant frame rate right?
How do you fix this?
CodePudding user response:
If you want a constant rate, then requestAnimationFrame
is not what you want.
requestAnimationFrame
will do its best to execute your callback before the next painting frame, and to not call it when it's not necessary, e.g if your computer is too busy to perform a render, or if your page is not visible to the user.
So indeed, when the tab hasn't the focus, no callback will be fired, but even when it has the focus, you can't expect a stable rate, anything happening on the user's computer can prevent the browser from rendering the page at the expected time, and every user may have a different frame-rate based on their monitor's settings.
There are a few hacks to keep a constant timer even when the page is in the background (e.g using Web Workers, or the Web Audio API), but they won't be able to avoid the issue of the thread being blocked by another app, and these are hacks and may stop working at any time. Moroever you don't seem to need it.
From your description, all you need is to embrace the fact that you don't have a stable rate, and update your animation accordingly.
For this, refactor your code so that it uses a delta-time, as exposed in this answer of mine. This way, you don't need to worry about the actual frame rate, you can be sure that what we see at any given time is at the position it should have been.
CodePudding user response:
as per MDN :
requestAnimationFrame() calls are paused in most browsers when running in background tabs or hidden s in order to improve performance and battery life.
You can't rely on requestAnimationFrame() if you want to do things while the tab is in the background.