HTML5 and JavaScript Continued – New Dev Environment & Animation

Continuing on from my basic getting started post, I want to continue covering some more basics of my HTML5 and JavaScript development.

Changing Development Environment

One thing before getting to the actual JavaScript, I wanted to highlight a change in my development environment. I previously said that I began with Notepad++ and then moved to the Visual Studio behemoth for my development needs. In the office, I moved to Sublime Text 2 for my day-to-day text (mostly non-code) editing based on over-the-shoulder previews of what it could do and a quick trial to get used to the look and feel.

A few days after making the change I heard about Sublime’s scriptability on twitter where some devs were using it to lint their Lua code. Other than the clean interface, syntax highlighting and code completion features, I wondered what Sublime’s scripting could do for streamlining my HTML and JS development workflow. I managed to find this post on the Sublime Text 2 forums which highlighted how to create a plugin that would load the current page in a browser. The only thing missing from this was how to save the current page before loading in a browser to avoid “I’m sure I just fixed that – why’s it not working!?!” syndrome.

This script is now bound to the F5 key in my Sublime and that’s massively improved my productivity. Here’s my version of the script (it’s Python so tabs are important but the blog may have scrambled them):

import sublime, sublime_plugin
import webbrowser
class OpenBrowserCommand(sublime_plugin.TextCommand):
 def run(self,edit):
  url = self.view.file_name()

and my key binding:

{ "keys": ["f5"], "command": "open_browser" }

Choosing a Framework

One other thing to note before I start was how I chose the framework that I’ve decided to use. For me, a lot of the fun of this development comes from finding things out for myself and learning new things. I understand the value of frameworks especially in the case of rapid development and wanting to get something to market, possibly on different platforms. Since that’s not my situation and I just want to learn and explore, I’m going to skip using a framework (although I’m keeping an eye on those that exist) and try and do as much as I can for myself.

Bring on the FPS

So back to coding and speaking of games, there was one FPS I wanted to look at before I got much further – Frames Per Second! I do know that FPS isn’t the best way to track performance, so I’ll include a millisecond time as well. All I really wanted was an initial figure to know when I’m not running at a playable speed (and I’ll worry about timing CrossFire/SLI performance when it comes to it). Basically if the refresh rate of a cleared screen on an iPad 2 couldn’t hit 60fps, then I was thinking I’d either have to give up or try something else.

Initially I thought if I couldn’t clear the screen each frame and redraw my scene, there was no other way to do it. Then I realized trying to clear a whole retina density display might not be the best way to go anyways. Since I come from a world of 16 milliseconds and change per frame, it’s difficult to twist my head around not redrawing the whole screen every frame where the only alternative is implementing something that selectively overdraws existing content rather than clearing and redrawing, and that’s a whole different mindset.

I started by creating the most simplistic FPS class that I could (all by myself! although it was several months ago now) which was my first use of  JavaScript classes. With the class written, I created  a simple test page that could give me an idea of performance when clearing the screen and rendering a couple of lines as fast as possible using setInterval() with a one millisecond interval. At that time, I ran that test in Chrome (which is my current weapon of choice for running my test pages). That was the only time I’ve really used setInterval() and the page updated at 80fps (not that I can remember the Chrome version number) .

Proper Animation in HTML5/JavaScript

The current wisdom is that for proper animation you should use requestAnimationFrame() to allow the browser to decide on the callback rate, rather than hardcoding an interval between frames. The best reference for requestAnimationFrame() I’ve found is (with the draft spec here). Creating a new FPS test to use this highlighted a change in performance, then running at something like 120fps. This was so different that I’ve got two versions of the FPS Test page, one for setInterval() and another for requestAnimationFrame(). It made me smile that the explicit “run as fast you can” setInterval() version updates less frequently than the “run when allowed” requestAnimationFrame() version. (And just to note, I got similar results on Firefox). One other thing to note is the time taken between calls needs to be checked since requestAnimationFrame() will pause on inactive tabs (as mentioned here) so you may see large time deltas.

It was shortly after trying to use the animation delta to make the animation in my test app smooth that I re-read the requestAnimationFrame() pages and I realized that (according to the chromium dev design doc here) the animation shouldn’t go any faster than 60 FPS. At this point I discovered my first big ol’ bug which was that both my common startup code and per-test local startup code kicked off the draw() function which reregisters itself with requestAnimationFrame(). With 2 initial calls, the system was running 2 instances of draw, both of which were updating the FPS counter – schoolboy error. Once fixed, the requestAnimationFrame() code now runs at 60 FPS, effectively frame-locked. I can now see the value of something like setInterval() as something less vsync’d, for example if you want to get a better idea of performance use setInterval() but ship with requestAnimationFrame().

Next time

To be continued with more development and possibly even a little game next time…


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s