Evaluating 8 Months of Building a Rails Vue SPA

yosemite Picture unrelated by Pexels

Over the last ~8 months I have been building a website called PikaTrack using Rails for an api backend and VueJS frontend. I wanted to write a blog post detailing how it went, what the positives and negatives are and would I do it again. The website is an open source service for fitness tracking using gps logs captured while running or cycling.

I’ll start with my background. I have been building websites in rails for about 3 years before I started this project. All of these used server side rendering with a minimal amount of JS for powering forms and interactive editing tools. Before starting I had never touched npm or webpack. Going from this to a dive in the deep end of the JS ecosystem was a little rough and a lot of the starting issues for this project can be explained by the fact this was the first time I had ever done this.

Why did I choose a SPA over SSR

I’ll give the reasons for why it was a good or bad idea but the actual reason I chose to do it was because I was interested in the idea and wanted to learn something new.

The benefits

Easily build an app on top of an existing api

PikaTrack requires a mobile app. One of the well known upsides of a SPA is you get 1 api that can be used on both the website and app. I investigated building a mobile friendly web app but I require the ability to keep the device awake and to record gps. This did not seem like an allowed ability for a website and requires deeper system permissions.

Have a first class public api for zero extra effort

Another benefit is the ability to provide a first class fully featured api to the public for building tools on top of pikatrack. Quite often with SSR websites the api will be an after thought which doesn’t allow the same feature set as the website. With a SPA I have a fully tested, fully featured public API for free.

The negatives

Throwing away things you get for free

A rails SSR website and the browser give you a lot of useful stuff out of the box such as error screens and zero config. When you build a SPA you now have to build in logic for what happens when the network connection goes down because you won’t see the browser offline page anymore. By default with a SPA you see no feedback at all when a request fails. There is also a bunch of configuration at the start of the project for connecting up the frontend to the backend, this just works by default on a rails SSR website.

Less tight integration with the backend and frontend

Rails allows you to run ruby code and gives deep access to the backend from inside the frontend templates which is quite convenient. With a SPA you are required to put all the data you might need in an API response to pass it over to the frontend. This may be seen as a positive as well as running this code in the template is a bit of an antipattern when it would be best done in the controller.

The neutral / not applicable

SEO

I have no idea what the current state of SEO on SPAs is. Some say search engines are able to run them and some say not. In any case it doesn’t really matter because my app mainly contains charts and maps that are only interesting to the person who submitted them and friends. There is nothing to search and no reason to search the app.

Requires JS to run

It is true that the website will display nothing but a landing page if JS is disabled but I don’t count this as a negative. A single JS file is downloaded from the same origin. There are no tracking or ad scrips bloating up the page. The main library, VueJS is very small and the website has been tested on older computers and runs fast. I make no attempt to support old browsers but I will ensure that older computers running modern browsers can use the website.

How it went

Initially the SPA configuration was seriously slowing me down because things like forms and routing were totally different to how I had been doing things in rails. But after the first few weeks and everything was configured properly it has become a non issue, everything I was doing in rails is now easy in a Vue SPA. The only thing that is bothering me now is that if I have a dropdown for an enum column I used to be able to use active record to get all the valid options for the select, now I have to either create an API that sends over the valid options or hardcode them in both the rails model and the frontend form.

Overall I am quite happy with the Rails + Vue SPA setup and think it was the right choice for this website. For simpler websites like my blog its totally unnecessary when much simpler tools like a static site generator do fine.

I understand SPAs get a bit of a bad reputation but I feel that this is largely an implementation issue and they can be done correctly if care is put in to optimise performance.

In the long term I plan to evaluate delegating some parts of the app to high performance Rust code. This will hopefully be made easy by the fact that the frontend is only depending on a JSON interface and not specifically requiring the backend be rails.