Skip to content

Javascript requestAnimationFrame()

You could say I have lived behind a rock in the Javascript world in the past two years. I recently developed Typing Mania in pure Javascript, which I intend to be my own replacement for the Flash-based TypingMania Odyssey, which for some reason I can’t set up properly at all.

Because I haven’t been following what happened in the Javascript world recently, I did not know that requestAnimationFrame() exists. I use setInterval(func, 20) as my main loop.

For some reason I decided against using <canvas> in this development – everything is composited from <img>, <div>, and <p> blocks with CSS formatting. At first, this worked well, until I added decorations and labels. As the number of elements grows, performance drops considerably (sometimes to only 15fps during gameplay).

This is quite disappointing. I know the bottleneck is in its DOM interface – the time needed to add/remove/change all the DOM elements is high. I even tried to minimize the number of DOM changes, but it did not get faster.

I tried searching for a solution again today, and viola, I found requestAnimationFrame(). It works perfectly, delivering a constant 60fps even for the toughest session. I am happy.

Searching around, I see that a lot of people said that requestAnimationFrame() is not suitable for the main game logic loop because it is not guaranteed to be called at a constant interval. Come on, people, you are seriously writing code that depends on a loop running in constant time?

I have always structured my Game/GUI application as follows:

  • Input are handled in the input handler. Anything that depend on external data (i.e. network) are processed immediately, otherwise, they are queued for main thread or scheduled to be process in another thread.
  • Logic is either processed by another thread or just before the rendering process in the main thread, but requiring deltaTime since the last time the game logic was processed to fast-forward the states correctly.
  • Rendering is done in a render loop. This reads data from various structs/classes and compiles the display.

This looks completely normal to me. This also has no forwarding-delay/logic-breaks-because-deltaTime-is-different/etc problems I saw people warns about regarding requestAnimationFrame().