When I initially sat down to write the Network Graph two years ago, I chose Adobe Flash for two primary reasons: 1) I was already familiar with Flash, having worked with it professionally, and 2) plausible alternatives such as Canvas and SVG were poorly supported across browsers, buggy, and slow.
Times have changed, however, and the HTML5 Canvas draft specification is now almost fully implemented on the latest versions of Chrome, Safari, and Firefox. Opera supports Canvas but not the text API. Canvas is missing entirely from Internet Explorer, but the word on the street is that IE9 will finally offer support. In the meantime, the open source community has created excanvas, a way to get Canvas support on current versions of IE.
To make the job as simple as possible, I decided to make the Canvas version of the Graph as much like the Flash version as possible. With the exception of a few tiny details, the Canvas version should behave identically to the Flash version, and it’s unlikely that you’d even notice the difference unless you were looking for it. In fact, I pushed the Canvas graphs to production yesterday, right under your noses! For now, browsers with proper Canvas support will see the Canvas version and everyone else will see the Flash version. For an example, see Ernie’s Network Graph.
As I was coding the new Network Graph, I jotted down a few notes about how Canvas compares to Flash. There are some areas where Canvas is a breath of fresh air compared to Flash, and others where Flash is clearly more refined. I expect many other developers will be doing Flash to Canvas conversions of their own in the coming months, and so I present to you a collection of these thoughts, in case they are helpful.
The Flash version of the Network Graph was comprised of 1,215 lines of code while the Canvas version comes in at 1,064 lines. Not a huge difference, but less code is less code. Where Canvas really shines is in the final deliverable. The compiled SWF file clocks in at 111k compared to the minified Canvas version at just 25k!
NOTE As was pointed out in the comments, this comparison is not entirely fair since the SWF contains an embedded font and the animated loader gif. On the other hand, I’m quoting the raw size of the JS while it is actually sent over the wire gzipped. So for the sake of true fairness, I compiled the SWF without any assets and gzipped the minified JS. It turns out that the SWF ends up at 19k and the gzipped JS wins again at a mere 6k!
Flash is not well supported on Linux and a variety of other operating systems. Compared to many sites, we have a disproportionately high percentage of Linux users. Because of this, it’s been a long-running complaint that we use Flash for the Network Graph. With excellent Canvas support in the latest versions of the browsers that Linux users use the most, Flash becomes increasingly less desirable.
Many of today’s modern browsers have excellent inspectors and debuggers. It’s great to be able to use these to see what’s going on in your Canvas project. Getting log output from an embedded Flash component is a huge chore, but with Canvas you can simply use
console.log to output status messages to the inspector.
Since canvas is a proper HTML element, it can receive mouse and keyboard events without any extra hassle. This is quite nice for the Network Graph since it allows you to scroll left and right with the keyboard as soon as the page loads, instead of having to focus the Flash component first.
Probably the biggest difference between Canvas and Flash is the level of abstraction available. Canvas is really just a low-level 2D graphics API. There are no objects or layers or groups or anything beyond what you need to draw various shapes and lines and text on the canvas. Flash, on the other hand, gives you all kinds of constructs that make it conceptually simpler to work with objects.
For the Network Graph this is a huge difference. With Flash I can simply draw all the commit dots and connection lines onto a single, large layer and then position that layer to reflect the current viewing region. But with Canvas I have to manually redraw the Graph any time the state changes. In addition, to keep things snappy, I have to calculate which commits and connections are currently viewable and ONLY draw those. This results in a substantial amount of code that is completely unnecessary in Flash. Flash computes all that for me.
It is certainly possible to create a framework that takes care of these details, and over time I expect some very good options to arise. For now, there is CAKE and my own Primer, but neither of those were suitable for this project. I do plan to work more on Primer and eventually convert the Network Graph to use it, but that will take time.
With Flash, you can embed fonts right in the SWF and you don’t have to worry about how fonts will render. With Canvas you’re once again at the mercy of the browser. Depending on what fonts are available to the browser, the final rendering may be drastically different.
Flash allows you to render HTML fragments to the screen. Canvas does not. Though the draft spec does have this to say:
A future version of the 2D context API may provide a way to render fragments of documents, rendered using CSS, straight to the canvas.
So Canvas may get this functionality in the future, but for now we’re out of luck.
One of the biggest benefits of Flash is that you only have to target one implementation: Adobe’s. With Canvas, you have to worry about what API methods are implemented on each browser, what bugs each browser introduces that may not be problems on other implementations, etc. As web developers, we’re used to this already, but that never makes it feel any better. Fortunately, the browsers I tested all seem to obey the Canvas spec rather well, and I didn’t hit any show-stopper differences between implementations. Hopefully as Canvas matures, this statement will remain true.
Canvas is the future of 2D (and possibly 3D) graphics on the web. Sure, it has a few shortcomings, but as time passes, it will only get better.
My advice for web developers: if something on your site CAN be done in Canvas, it SHOULD be done in canvas.