requestAnimationFrame
is called whenever the screen is ready for a repaint.
On modern screens the refresh rate may be a lot higher then 60 frames per second. If there is a lot of stuff going on inside those calls - it may impact the overall performance of the application.
So my question is: shall the requestAnimationFrame
always be throttled down to 60FPS? Can human eye actually tell the difference between for example a 16ms and an 8ms repaint delay?
[UPDATE] I ended up throttling it down to 60FPS for higher performance on screens with high refresh rate. And would suggest this approach to everyone who has a lot of stuff goin on inside the rAF calls. You should do your own testing of course though.
requestAnimationFrame
is called whenever the screen is ready for a repaint.
On modern screens the refresh rate may be a lot higher then 60 frames per second. If there is a lot of stuff going on inside those calls - it may impact the overall performance of the application.
So my question is: shall the requestAnimationFrame
always be throttled down to 60FPS? Can human eye actually tell the difference between for example a 16ms and an 8ms repaint delay?
[UPDATE] I ended up throttling it down to 60FPS for higher performance on screens with high refresh rate. And would suggest this approach to everyone who has a lot of stuff goin on inside the rAF calls. You should do your own testing of course though.
Share Improve this question edited Oct 11, 2014 at 9:08 YemSalat asked Sep 30, 2014 at 12:26 YemSalatYemSalat 21.6k13 gold badges48 silver badges51 bronze badges 5- 2 Well, if there is lots of stuff going on inside those callbacks, then the next animation frame will necessarily be delayed. "animation frame" is not tied to the screen refresh rate! – Bergi Commented Sep 30, 2014 at 12:57
- Thanks for the ment! Do you have any reference by any chance? – YemSalat Commented Sep 30, 2014 at 17:46
- No, and in fact I might have been incorrect (see the quote from klyd's answer). The browser is smart and tries to synchronize framerate (js animation frame callback + reflow + redraw) with the screen refreshes for a smooth experience. However, it will automatically throttle it when there is (too) much js work per frame, the battery is running low, the tab is not shown etc. – Bergi Commented Sep 30, 2014 at 19:17
- 1 Just to avoid misleading ment to slip through : there's no such thing as automatic throttle. And no such thing as framerate synchronization. that's sad, but there's no magic here. – GameAlchemist Commented Sep 30, 2014 at 19:28
-
If the JavaScript code in the callback specified to
requestAnimationFrame()
runs longer than a single frame, then, yes, you will force a frame skip which is itself automatic throttling. You should only put things inrequestAnimationFrame()
if they are things which cause a user-visible change (such as calculating positions). Wanting to skip frames to “increase performance” will result in less fluidity in your animations and a perception of lower performance/jagginess on your page. – binki Commented Sep 5, 2022 at 22:14
3 Answers
Reset to default 8Per MDN it will not necessarily always be 60 FPS.
Relevant quote:
This will request that your animation function be called before the browser performs the next repaint. The number of callbacks is usually 60 times per second, but will generally match the display refresh rate in most web browsers as per W3C remendation. The callback rate may be reduced to a lower rate when running in background tabs.
As for can the human eye distinguish 60 vs 120 FPS, well, that's an open, and opinionated question. Some claim to see it, other's claim its impossible. Allowing the end user to choose is (or simply using their hardware to its fullest) probably best.
As markE's ment pointed out. The requestAnimationFrame
callback receives a DOMHighResTimeStamp
which is a high precision timer accurate to the "thousandth of a millisecond." By using this time-stamp, and calculating the delta between frames, you can tune your refresh rate to whatever desired value.
References:
- requestAnimationFrame
- W3C Timing control for script-based animations
- DOMHighResTimeStamp
Note: please remember to leave a ment addressing any downvotes, otherwise they are not useful feedback.
I guess that people having 120hz or higher frame rate displays are aware that it requires more resources to generate twice as much frames.
That and/or they have more powerful puters than most users. I personally have a very powerful PC but two 60hz displays and the only guy I know that has a display with a higher framerate than 60hz is a pro gamer so obviously he has no performance issue when browsing the web.
Also, people using very high framerate displays are getting used to that level of fluidity and they might notice the difference (event if I doubt it).
My two cents are : respect their preference of having an overkill display. It's what they want.
By default, i think it is good to limit the framerate to 60Hz, since :
• High framerate means more heat, so the (cpu) fan noise will be annoying.
• For most game nobody will notice.
• it's easy to do.
• For those with ecological concerns, high fps uses more power (==> more CO2).
About the visual interest of 120 Hz :
For 2D games where only a tiny amount of the screen is actually changed between each frame it's of little to no interest.
For 3D games, especially those targeting to be realistic, using 120Hz allows to get a more 'cinema'-like experience.
Why ?
==> Most 3D renderers only render a scene at a point in time, so what you see is a succession of 'perfect' still images.
On the other hand, a real camera will -like the human eye- be kept open for a few milliseconds, thus the moves happening during this time will leave a trail on the image, providing a more true to life experience.
The 60Hz boundary is only enough to fool the eye about the motion, so what the 120Hz+ screen brings is that the screen is so fast eye remanence cannot follow and you have again that camera/eye trail effect.
The code looks like :
var minFrame = 13;
var maxFrame = 19;
var typicalFrame = 16;
var gameTime = 0;
var lastDrawTime = -1;
animate(drawTime) {
requestAnimationFrame(animate);
var dt = drawTime - lastDrawTime;
lastDrawTime = drawTime ;
if (dt<minFrame) return;
if (dt>maxFrame) dt=typicalFrame; // in case of a tab-out
gameTime+=dt;
// ...
}
function lauchAnimation() {
requestAnimationFrame ( function(t) { lastDrawTime = t;
requestAnimationFrame(animate); } );
}
Rq1 : When you limit the fps, you must take care of the fact that the frame rate is not stable at all in a Browser.
So even with an application doing nothing, on a 60Hz screen, has frame duration that can go from 14ms to 19ms. (!!!!) So you must take some margin when capping the frame rate to some value.
Rq2 : In the example above 'typicalFrame' is to be replaced by the native screen frame rate (that you have to pute by yourself).