iD depends on SVG for drawing map features, displaying tiles, and a model upon which to build complex interactions. In the process of building it, we’ve learned a lot about SVG’s performance equation – and it’s time to share some of this. A lot of this is taken from NOTES.md, a sort of developer-journal which has grown over the last few weeks. note that the examples in this post are designed to run around ~30fps in Google Chrome on a fast computer. They’re made to push the limits, so may crash slower browsers on slower machines. We’re generally using d3 for graphics in iD. It’s a very, very light abstraction layer over SVG – it eliminates the need for manual namespacing, gives a jQuery-like chainable attr setter, and so on. Besides just having more shapes, SVG has different concepts – one is the <,g>, element, that represents a group. The groups can be very useful, since they can be transformed with the transform attribute: for instance, markers are set up like SVG’s defs element is another oddball: it defines content that doesn’t show up on screen, but can be used via reference: I’ll mention this later on with textPath as a example. But another usage of defs for this project is making a rect element which is used to clip the vector and tile layers. For panning the map, transforms seemed to be the main solution – they allow simple pan behaviors to be carried out on a single element, and in a way that doesn’t require a browser to recalculate individual element positions. However, early results were not encouraging – CSS transforms, even of the ‘hardware accelerated’ 3D variety – are not accelerated in Google Chrome when used with SVG elements – they have the same performance profile as SVG attribute transforms. The answer is to transform HTML elements, which does trigger fast code in Google Chrome. In iD we do this by transforming a ‘surface’ element (the SVG parent) of the map instead of the group (<,g>,) elements that make up the tile surface and vector surface. Vladimir brought up this one and I didn’t expect it to be a significant bump, since SVG is vectorized, I assumed that it wouldn’t have raster-pixel bumps like Canvas does. However, it is a boost, and not just because of the shorter string length of d attributes – rounding and outputting long fixed-point numbers is also faster than non-rounded values. This is about a 20% improvement in testing. One of the features we need in iD is an indication of roads that are one-way, and which way they are going. SVG has some built-in functionality for this purpose – you can define a marker in a defs element and use it on path elements with marker-mid and so on. Unfortunately, this doesn’t cut it, since OSM paths have an extremely variable number of vertices – some straight lines have hundreds of vertices, some have only a few, and would be very sparsely labeled. Our current solution to this is to use a textPath with a glyph – a right-facing triangle. Here’s what it looks like in a standalone demo. Then getTotalLength lets you get the pixel-length of a path, and you can then use multiplication & letter spacing to distribute just enough markers for the path: Update: I noticed that this example is broken in Firefox. This is due to the following (also noted on the example page): The original version of this failed because Firefox does not support letter-spacing on SVG elements. The second version failed because it has a bug in getComputedTextLength. The third failed because it does not preserve space according to xml:space. Needless to say, Firefox is not the main target for iD testing because of a buggy and incomplete implementation of SVG relative to WebKit. Much of this work is currently focused on improvements to OpenStreetMap funded by the Knight Foundation Follow our work here on this blog or subscribe to our Twitter feed. You can subscribe to this blog’s feed or follow us at @mapbox Source.