If you look for a quick solution, I have bad news: It’s not possible. Not even close. Well, in the browser at least.
For many subsequent years, smart web developers have tried and failed to produce accurate ways to measure something that comes close to displayed frames per second on websites. Something that’d been so vital to the gaming industry for decades can’t be that hard to measure, right?
In the web world, fps map closest to redraws. Redraws (or repaints) happen when anything on screen needs to visually change (if the layout changes as well, an additional reflow/relayout will be done). Many implementations tried to address the same problem:
- running intervals at ~16ms (60fps) and check how long they actually run to produce a number
- changing the width of a DOM element and read out the offsetWidth to see if the new width has been applied
- Internal browser debug tools (namely Chrome and WebKit)
- the Mozilla-only MozAfterPaint event
I have tracked all of them down for you so you don’t have to try them out only to find out later that you’ve been tricked. Yes, none of them actually work. Yes, it’s a bloody nightmare.
Running intervals is never reliable – it just tells you that the JS execution is taking time, or sometimes not even that – many browsers throttle intervals artificially in some cases. It gives you no information whatsoever about painting. Changing the width of an element and reading back the offset values is better, as the numbers are smaller (smaller = more realistic), but too small – you want redraws only, not expensive reflows. Internal debug tools, such us the WebKit Debug menu or Chrome’s flags will show an FPS counter but no FPS. Rather, the opposite – Chrome’s FPS counter goes up when lots of stuff on screen happens, and goes to zero when the browser idles. The MozAfterPaint event wasn’t reliable when I tested it many months ago. The same goes for requestAnimationFrame.
I honestly don’t know why requestAnimationFrame is such a let down. It was supposed to be the cure for all our fps needs. Browser vendors told me over and over that this is the number I’ll want. Well, it’s not. I trust my vision more than your API. And I know when the counters are lying. You’re telling me 60fps when I’m clearly seing 20.
Update: I get the feeling that it’s wrong to blame requestAnimationFrame – it’s not even meant to report the number of draws, but rather informs you when you theoretically might be able to draw. I need feedback instead.
Seriously now. Can somebody please fix this?? You’ll be my personal hero for a month and I’ll buy you a nice german beer.