The state of cross-browser vector graphics

Vector graphics have for long been the preserve of Flash on the Web as browser vendors never agreed on “one standard to rule them all”. But intrepid newcomers relying on browsers’ native features might well change this situation…

A bit of History

Microsoft first proposed their own standard to the w3c, VML, which was later merged with Adobe’s PGML to give birth to the SVG recommendation.

However, Microsoft chose to support vector graphics in their browser before the corresponding working group of the w3c had a chance to publish their first recommendation: VML was implemented in IE5, released in March 1999 while SVG1.0 was only published as a recommendation two years and a half later in September 2001. On the other hand, partial support of SVG was not to be found before Firefox1.5, released in 2005.

Even though VML was the first technology of its kind to be natively supported in a browser and although this browser could have taken pride of its monopolistic usage share for several years (above 90% between 2001 and 2005 according to different sources), it remains unclear why this technology never really took off… On the contrary, the fate of SVG, never supported by the dominant browser is much easier to understand.

A bit of Technic

From a Web developer perspective, it is arguable that the main advantage of VML lies in its deep integration in HTML:  it is possible to nest HTML elements in VML ones and vice versa. SVG was meant to be an independent specification, the result is that it has to be used in a specific namespace in HTML documents, and HTML can only be used in SVG when nested in a <foreignObject>, an element poorly supported in the earliest implementations.

However, SVG reveal all its power when it comes to transformations: rotations, translations, skewing and other scaling can be nested in any ways where different attributes, filters and computations have to be used in VML.

A bit of hope…

Meanwhile, Adobe’s claim of a 99% browser penetration of its proprietary but nonetheless fully vector based Flash technology obviously succeed to seduce a significantly larger number of developers. Nevertheless, two projects saw the light of day with the promise of providing a cross-browser vector graphic API relying on an abstraction layer above VML and SVG:

  • Dojox.gfx, an integral part of the dojo toolkit specialized in 2d graphics. Its main advantage is that it does provide “one API to rule them all“: its set of shapes, paths and transformations can be rendered either to VML, SVG, canvas (the scriptable raster graphic element of HTML5) or Silverlight (details follow). It is shipped with helpers to make elements movable and to render vector fonts, although its supposed negative impact on performance makes it only suitable for a limited amount of text (see the Caveats section of the page).
  • Raphael, a library agnostic (i.e. autonomous) library which offers a clean API mimicking jQuery’s one. It provides the same basic features as dojox.gfx together with animation, color manipulation, event handling, and vector fonts (as of version 0.8) right out of the box (animation and color manipulation are integrated in other parts of the dojo toolkit).

Both libraries can be used in a similar way: first, the area where the drawing will be possible is defined. In Raphael it is called the paper, in dojo.gfx it is the surface. The function that build this area returns a reference not on the physical DOM element that has just been created but on a more abstract JavaScript object that offers methods independent of the browser. The following kind of code is always to be found at the beginning of a script using on of those library:

[code lang="js"]
var area = createArea( positionOrParentElement, dimensions);
[/code]

Using this reference, any shape or path can be created, once again those functions return an abstract reference on the created shape:

[code lang="js"]
var rectangle = area.createRect( position, dimensions);
[/code]

And this reference can in turn be used to dynamically modify the attributes of the element, to animate it or to delete it:

[code lang="js"]
rectangle.setAttribute("fill", "red");
[/code]

This kind of code should look familiar for any developer used to JavaScript libraries such as jQuery, prototype and of course dojo. There is however an important difference: in the latter libraries, it is possible to find an existing element in the DOM and use it to build an abstract object:

[code lang="js"]
var existingElement = library.domQuery("#myDiv");
existingElement.animate({'opacity': 0.5});
[/code]

Using vector graphics, this abstract object is only created when the associated physical element is inserted in the DOM. The reference that is returned must be conserved as long as the element needs to be modified. This fact turns out to be important when doing event delegation. With a traditional library, modifying the opacity of all list-items of a list on mouse click could be achieved with the following code.

[code lang="js"]
// A function will be executed every time the user clicks on the list
library.domQuery("#myList").onClick(function(event) {

// The event object references the physical element that has been clicked
var physicalListItem = event.target;

// The library can build an abstract object from this existing element
var abstractListItem = library.abstract(physicalListItem);

// This object can then be used to modify the properties of this element no matter the browser
abstractListItem.animate({'opacity': 0.5});
});
[/code]

Unfortunately there is no such thing as

[code lang="js"]
vectorLibrary.abstract(physicalShape);
[/code]

But this can be easily circumnavigated by keeping a record of all abstract object associated in hash table with the id of the element:

[code lang="js"]
var abstractRect = area.createRect( position, dimension );
// Make sure the shape has an id
abstractRect.setAttribute(id, "myId");
// Store this reference associated with the id
var hash = { "myId": abstractRect };

area.onClick(function(event) {

// Event gives access to the id of the clicked shape
var shapeId = event.target.id;

// Which can in turn be used to recover the abstract shape
var abstractShape = hash[shapeId];
});
[/code]

The impact of such hash map on memory footprint is discussed in the paragraph about performances.

… and delusion

With the release of the 8th version of its Internet Explorer, Microsoft dealt VML a severe blow: several features appear to be broken, the most serious one being the possibility to use percentage units… What are vector graphics when the drawing cannot scale? It remains unclear whether those issues have been introduced unintentionally, what is certain is that it will help Microsoft to impose its new technology with vector graphics possibilities: Silverlight, a concurrent to Adobe’s Flash/Flex/Air Framwork also relying on a multi-browser plugin.

This inexplicable coincidence  leaves unfortunately only few hope for an happy ending to the epic battle of native vector graphics.

State of the art

Nevertheless, the baby should not be thrown out when Microsoft siphon off the bath water. It remains possible to use vector graphics in the browser as IE8 can be turned in compatibility mode to act just like the good ol’ IE7 used to. The two aforementioned vector graphic libraries still have to be compared… So be it:

Features

In terms of feature richness, the advantage seems to be for dojox.gfx: As far as as shapes, paths and transformations are concerned, the two APIs are equivalent. Both libraries offer animations, color manipulations and event handling, although this is lies in a lower level part of dojo. However, the alternative technologies that dojo can use to render the graphics might give it a real benefit: Silverlight makes it a more future proof solution and canvas even allows a server-side rendering into raster graphics. Moreover, Raphael does not allow to use other units than pixels, this one being hard coded in the library.

File size

In term of file size however, analyzing the loading process of the two solutions with Firebug yields a size of approximately 22kB for Raphael (once minified and Gziped) and a cumulative 40kB for dojo (when loaded from AOL’s CDN). In one single file, Raphael ships all its utilities and both SVG and VML rendering code, whereas the utilities of dojox.gfx adopt a lazy loading approach with its utilities spread throughout inter-dependent files and a single rendering code being loaded according to the browser capabilities. Even with lazy loading, dojo is almost twice as big… This can be an important criteria for developers who do not intend to use the full capabilities of dojo or who have chosen another JavaScript toolkit. In the latter case, it can be noted that even Raphael will be duplicating some features commonly found in JavaScript libraries: animations, color manipulation and event handling.

Performances

In order to evaluate the impact of storing all references on abstract shapes, two tests were built: a thousand rectangles were created in a page and then in one case all the references were kept in a table to change the color of the rectangles, whereas in the other case no references were kept. It appears that storing the references has a negligible impact on memory footprint in Firefox3. However, in Internet Explorer 8, it turned out that Raphael systematically caused the browser to freeze. The test would complete only when it was limited to 500 shapes, but after 30 seconds of delay. The profiler shipped with IE8 revealed that the lag was mostly caused by the internal setBox method of Raphael that is specific to the VML code.

It should also be noted that Raphael does not offer event handling at the paper level. Event delegation is thus impossible when the library is used in standalone despite the benefit of this method on performances (even listeners are set only once on a container instead of being set for each elements).

Documentation

Last but not least, the quality of the documentation can in many cases tip the scales.

Raphael offers a documentation of its API which includes useful code snippets, however some utilities for color manipulation such as Raphael.hsb2rgb(), Raphael.rgb2hsb() or Raphael.getRGB() are not yet documented. On the projects’ home page, numerous visually appealing and inspiring examples can be found such as a dynamic graph, a start point for a mind map and a demo of the vector fonts. It can be argued that an example with detailed code comments is lacking.

Dojo offers a complete and up to date reference of its API where the documentation of dojox.gfx can be found. However, developer not familiar with the dojo toolkit should read Dojo, Now With Drawing Tools to get started. This article also provide more advanced examples with appropriate comments.

Choice is yours

Dojox.gfx is a natural choice for any developers working with dojo while Raphael is more suitable as a standalone library thanks to its smaller file size. When a large number of shapes have to be created at once, the performances of Raphael should however be evaluated in Internet Explorer. The ability of dojox.gfx to render graphics using Silverlight or canvas can prove to be useful in some case.

For developers already using a JavaScript library other than dojo, it should be noted that in both cases, there will be some code redundancy. Moreover, if performances are critical, the file size of dojo and the problem of Raphael might even prevent to choose any of those…

One thought on “The state of cross-browser vector graphics

  1. Glimpse

    Very interesting article! Thanks!
    I have to develop a graphical editor right in the browser and I’ve decided to use SVG with RaphaelJS. I hope this is a good choice…

Comments are closed.