What I Learned from SVG Tool Development

This past few months I and my friends are developing an SVG manipulation tool for our hobby project.
This tool is not the end-product but more of a helper for data extraction and manipulation. It is web based and currently built with ASP.NET MVC, SignalR and Angular.js.

What I Learned from SVG Tool Development - Image 1

As you can predict from the screenshoot above, it is javascript heavy. The development of single page app is much easier nowadays.

One thing that still surpsised me was that SVG manipulation is still relatively slow on non Chrome browsers. In our case, when we loaded more than 10k path elements, it took some time in IE and FF.

Until now, Firefox still doesn't support important APIs like getIntersectionList(). This method was important since we wanted to detect all SVG paths related to mouse click position. We changed our UI flow and then we relied on path's click event.
Mouse event's offset is still not supported in Firefox so we rely on layerX and layerY property

return evt.offsetX || evt.originalEvent.layerX;

It is kind of nostalgic that before jQuery became popular, it was common for us to handle browser API differences manually.

We also had issues of uploading large amount of JSON data, for save feature.
Initially we tried using single web socket call but apparently SignalR has message limitation of 32 kB. Obviously it is a bad practice to send large file via web sockets.
We managed to use workaround by calling multiple AJAX calls, which was not ideal.
In the end, we use Blob API in XHR2 so it can be done in single AJAX call.

For data storage, we initially use sessionStorage API.
It worked well until we learned that the few of our source SVG files contain a lot of paths. It exceeded max size limitation of sessionStorage. From what I read, there was no way to increase sessionStorage in a browser.
IndexedDB came to the rescue.
Unfortunately one thing solved, another issue appeared.
The refactoring process became more complicated because the indexedDb itself is anyc based API. The problem was we wrapped local saving inside a class which derived from MenuCommand. All other implementations of MenuCommand's execute method was sync. The solution was we returned promise object. However async method are still infectious.

The last thing, based on our scenario, we are also considering to ditch web socket for normal AJAX calls. We rarely need to communicate with server to justify additional resources. Obviously using newer communication protocol feels cooler but it may not be needed in our case.