Frontend vs Backend (To Go or not to Go)
Tags: webdev, javascript, go, map
Published: 2022-11-21 08:03:42

Last few weeks, I tried to speed up Javascript. It could sound funny and weird, because many others, like Google, have been doing it for years. However, I do not delve to this too deeply. I've just investigated how to speed up my SmartShape Javascript library (https://www.npmjs.com/package/smart_shape) to load and manipulate large interactive vector shapes in real time on a web page. As an example for testing, I selected a "Natural Earth" database of countries - https://www.naturalearthdata.com/downloads/. It contains the countries' borders at 3 different scales: 1:110m, 1:50m and 1:10m. To make things simple, I exported it to GeoJSON format. So, the task is to load all countries from GeoJSON and convert them to SmartShape objects. Then assemble all countries into a single world map and convert this map to an SVG vector graphics file.

The input is an excerpt of the Natural Earth countries database that consists of 684 GeoJSON files. It's about 28MB in total size. Each GeoJSON file contains one or more polygons. Each polygon is defined by points in polar coordinates (latitude and longitude). The whole database for the experiment consists of 6188 polygons and 658287 points. So the goal is to load all these polygons to a web browser, convert their polar coordinates to screen coordinates, assemble them into a SmartShape object as a single world map, then scale it to specified width and height and render an SVG file from this data.

Actually this job was done successfully a week ago and I shared the resulting SVG file in the previous post on Linkedin https://www.linkedin.com/feed/update/urn:li:activity:6997894438991626240/. The Javascript code did all this loading and conversion work in 6 minutes and 21 seconds.

However, this process should not be done only once. It should work in real time. For example, when the user wants to resize the world map using the mouse, or add/remove countries from it. Therefore, this timing is unacceptable and I had been trying different optimizations, until finally decided to use Go. This is my favorite programming language for web backends and it performed really well. The Go code completed the same task on the same computer in less than a second (in 0.82 of a second, precisely), which is 465 times faster than Javascript. Go is wonderful, I always knew that. However, the idea to do everything in frontend, without needing to exchange data between backend and browser looked very attractive for this task. However, in-browser Javascript is TOOOO SLOOOOWWW for this. So, even if the Internet connection will be extremely slow when the generated SVG is sent from the Go backend to the browser, it will still work many times faster than an in-browser solution. On the one hand I think that it is possible to optimize JS code to perform slightly better. However, it will never be as fast as Go. Finally, I think that it's not an option to use a single tool for everything. Each task should be handled with the tool that will work best for it.

As a result, the frontend library has now become a full-stack solution. Now SmartShape has an additional option for huge shapes: to not render SVG drawing of shape by itself, but request the rendering process from an external source (like backend web service) and then display and manipulate already pre-rendered shape in a web browser. My research has some practical output. Let me introduce a new online service, which can be used to generate different vector maps and save them to SVG:

https://maps.germanov.dev

The source of backend service, that used to generate SVG maps is available here: https://github.com/AndreyGermanov/mapbuilder_backend

Generated SVGs contain only shapes without any styling. But it's easy to open it in any text editor and style it using CSS as needed. In addition, any visual editor that can open SVG files can be used for this.

Also, in the coming future I will add a feature to create and design vector maps visually in SmartShape Studio: https://shapes.germanov.dev.

Follow me to not miss anything.

LinkedIn: https://www.linkedin.com/in/andrey-germanov-dev/
Facebook: https://web.facebook.com/AndreyGermanovDev
Twitter: https://twitter.com/GermanovDev

My online services website: https://germanov.dev