Skip to content

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.

Given the current status of Canvas and the impending release of Apple's iPad (which will have no Flash support at all), I finally decided to bite the bullet and do a complete rewrite of the Network Graph in JavaScript and Canvas. All told, it took about four full days of coding to get all of the features of the Network Graph reimplemented.

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.

I'm quite pleased with the outcome of the project. I was a bit worried about how the JavaScript would handle the complex parts of the code, but modern JS implementations are so fast that performance is as good or better than the Flash equivalent.

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.

Where Canvas/JavaScript is better than Flash

Fewer lines of code and smaller deliverable size

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 works badly on Linux (and friends)

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.

Inspectable/debuggable via browser

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.

No compilation step

With JavaScript and Canvas, you can modify code in your text editor and then simply reload the browser page to see the results. With Flash, there is always a compilation step that gets in the way. I suppose there are workflows that mitigate this problem, but since I was using haXe for my source, I always ended up compiling the SWF file from the command line.

Better cursor handling

I'm not at all happy with how Flash handles cursors. Changing the cursor always seems to result in a laggy cursor that ruins the user experience and makes the entire Flash component feel shoddily done. With JavaScript I can change the cursor to a variety of built-in options that behave as they should. Custom cursors are still a problem in browsers since most do not respect the hotpoint in the cursor file, but just having access to a standard set of responsive cursors is a huge win.

No need to focus to receive keyboard events

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.

Where Canvas/JavaScript is worse than Flash

Have to handle clipping and redraw manually

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.

No embedded font support

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.

No built-in multiline text wrap

The Canvas spec does not include any way to automatically wrap text within a bounding box whereas Flash makes this task easy. It's not too hard to write a simple line wrapper in JavaScript, but I feel it's something that would be better served as part of the API.

No HTML fragment rendering

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.

Back to dealing with browser implementation differences

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.

Conclusion

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.

You can write it with the same language (JavaScript) as the rest of the interaction logic on your web page. It's fast and getting faster. Once a few competent frameworks appear, it will be just as easy to use as Flash for a huge variety of tasks. And once the iPad ships, Flash will become a liability.

My advice for web developers: if something on your site CAN be done in Canvas, it SHOULD be done in canvas.

Have feedback on this post? Let @github know on Twitter.

Need help or found a bug? Contact us.

Something went wrong with that request. Please try again.