Measuring HTML5 Browser FPS, or, You're Not Measuring What You Think You're Measuring

Update: Ilmari Heikkinen has written a helpful Browser Rendering Loop blog entry.

Everything you know is a lie.

OK, not everything.  But everything you know about measuring the FPS for your HTML5 game is probably wrong.  Turns out that measuring the frame rate, or FPS, for an HTML5 game written in Canvas or WebGL is surprisingly difficult. will tell you that trying to measure framerate by counting how often your setTimeout runs is not accurate. The browser can run your Timeout callback multiple times between screen paints.  All you're probably doing is measuring how often your game loop runs, which is not FPS.
Turns out Mozilla has a window.mozPaintCount available, which should provide an accurate FPS. However, this only works for Mozilla.
There's an open issue for a clone of window.mozPaintCount for Chrome, but doesn't look like there's much traction there.
A manual way to check for hardware accelerated FPS in Chrome is to grab the Chrome Beta channel (as of posting date) and go to about:flags and turn on FPS Counter. However, on a Mac, acceleration only turns on when using WebGL. So, no way to check FPS for Canvas on Chrome for Mac.
Enter requestAnimationFrame.  This little doozy works its butt off to get your game running at 60hz (in Chrome) or 50-60hz (in Mozilla).  Instead of writing your own setTimeout loop, you ask the browser to call your draw function when its ready.  Yup, that's right, you're putting your game's draw loop into your browser's hands.
This is a good thing, though.  The browser knows when it's painting, so it knows when do call your paint function.  This reduces tearing, as the browser can draw at the same time as your monitor's refresh.  Also a big win: if the tab isn't visible, the browser won't animate, thus saving CPU and battery.
One small hitch with requestAnimationFrame: Firefox 4 just fixed a bug (as of the date of this post) which gets the frame rate up to acceptable levels, but we'll have to wait for the next push of Firefox to get the fix (yay for autoupdates!)
Moral of the story is: you're probably not accurately measuring your HTML5 game's FPS, and you can only programmatically measure it in Firefox with window.mozPaintCount.
Second moral: Use requestAnimationFrame if your user is on Chrome, and soon Firefox 4.

Popular posts from this blog

Converting Array to List in Scala

I ported a JavaScript app to Dart. Here's what I learned.

Minification is not enough, you need tree shaking