When do you build a SPA vs. a server-rendered app?

_bigblind profile image Frederik πŸ‘¨β€πŸ’»βž‘οΈπŸŒ Creemers Oct 10, 2017

In a web app I'm working on, we're planning to move the front-end to ReactJS. I'm contemplating whether it'd be better to build it as a SPA (single-page app), where the server just exposes a RESTful API for the frontend to use, or a multi-page app, where the server renders parts of each page that don't need interaction, and we use React for the interactive parts.

What factors would you look into to make a decision like this?

markdown cheatsheet

This is a good question, and one I thought about before starting dev.to. I think it boils down to what the most important problems you need to solve today are, and what is going to be the most reasonable approach to doing that. Some apps need to be SPAs based on functionality, and some really do serve documents, more inline with the original vision of the web. Most are somewhere in the middle.

SPAs have the benefit of really leveraging the amazing functional UI patterns made popular through things like Redux. And they can provide the benefit of allowing the user to most easily download the app in good network conditions and have an uninterrupted experience if it becomes worse. That's assuming no further downloads needed.

"Traditional" apps have the benefits of less mental overhead a lot of the time and much better browser support for almost anything you'd want to do. If my primary goal is quickly serving a content-based web page to a visiting user, or serve a landing page for my service or something, trying to implement that as an SPA is potentially burdensome and can degrade the experience pretty easily in terms of performance for this case.

dev.to is architected like a traditional app with some code sprinkled on top to make it act like an SPA, and the SPA stuff, even if it's not a lot of code, has a reasonably high percentage of overall bugs. But early on the choice was to optimize for the basic "visit the site, have a pleasant experience reading an article, and leave" case. And while the site is evolving, this is still most of the overall traffic. So I'm happy we went with a more traditional approach and evolve from there.

Given recent developments like service workers and IndexedDB for storing data offline, could SPA's not work better in limited network situations? I'm assuming you can save a lot by only downloading the markup and scripts once, and having all other requests be API calls, with smaller responses.

I think it depends on the user story and your own capacity to make use of these tools. If you are getting a lot of first time users on the device or you just aren't getting enough local cache hits in general, the experience could suffer.

It's probably getting better but I feel like the last few years has seen a lot of people striving for the ideal web experience and falling short by rolling the dice on apps that take a lot of coordination to get right. But I'm mostly thinking about content-oriented websites with a basic offering that has become way to heavy and complicated on the front end. If the UI interactions are inherently complicated and require ongoing state maintenance, it's worth taking on those.

The app I'm working on doesn't require much local state, but it'll frequently be used repeatedly by the same person in low connectivity situations, so I'm thinking of going the SPA route, to make as much use of local storage as possible.

Cool. I think you're making the right call then. Any idea what the stack will look like specifically?

(P)Reat on the frontend, Django on the backend. Possibly preact.io in between the two, but I'm not sure about this, since it potentially increases the amount of data you download again; The cached JavaScript may already have the template you need in order to render the frontend, yet the server sends a bunch of markup.

If I remember correctly, you're using Preact on dev.to, right? Are you noticing the differences with React much?

That's the plan, but so far it's still just a plan and has only been fooling around with it outside. Haven't implemented it yet in anything on the site yet. We're pretty methodical with this stuff.

For me it really depends on the type of site that you're building. If Service Worker is something you're going to want to add later then the SPA approach makes it a lot simpler, but is definitely possible with a SRA.

Me personally, if it's more of an app you're going for then I'd do SPA, if it's more of a site, then go for the server render.

Yeah, I agree. And while you don't want to use the same hammer for everything, but if you're particularly excited about or confident in a technology, you might just want to go with that and deal with the pitfalls as they come.