Single Page Applications get a lot of their speed and responsiveness from not constantly reloading the browser, tearing down the application process, only to reinitialize it on the very next page.

These are web applications making heavy use of JavaScript, using frameworks like ReactVue, or Ember. The initial page contains all the JavaScript to make the application work, and it behaves like a desktop application. Hence these websites are called Single-Page Applications.

Instead of fetching an HTML response from the server, these JavaScript frameworks ask for the JSON data, interpreting and rendering the JSON on the frontend. The browser doesn’t have to reload the whole page; JavaScript does most of the work.

request-response-json.png

A good example of a single-page application is the Rails forum powered by Discourse. When you click on a message on the forum, the browser doesn’t reload the whole page, unlike a link on the MDN documentation, which uses the traditional web architecture. Notice how the full page reloads whenever you click any links on MDN, but not on the Rails forum.

Disadvantages of SPAs

Single-Page Apps have a few disadvantages, such as when you first load the application, it is slow, as you have to load a big JavaScript bundle. To solve that, you have to compress and link together all JavaScript using a bundling tool like Webpack, which is not a simple process.

Also, you might have to duplicate the view templates both on the frontend and backend. Managing and sharing links also becomes tricky, as you are always on the same page.

SPAs are also not very SEO - friendly. As Barry Adams explains,

What happens when you use React without server-side rendering is that the crawler halts on the very first page because it can’t see any hyperlinks to follow. It sends the page to the indexer, which then has to render the page and extracts the hyperlinks, which will then be added to the crawler’s queue.

Then the crawler will eventually crawl the next set of pages, and again will stop there because all the links are invisible until the JavaScript is rendered. So it has to wait for the indexer to come back with a new set of URLs to crawl. Etc.

It makes the crawl process incredibly slow and inefficient.

In my experience, most of these "modern" SPA apps (and I mean most business applications, not the slick demos you see on the React or Next.js websites) are fragile, poorly implemented, have bad first-load times, don’t work well with the browser’s back and forward buttons, and cause a bad user experience.

To be honest, many web applications just don’t need the SPA technology, with big, honking JavaScript frameworks and specialized teams. They’d work just as well, if not better, using plain, boring, old web architecture.

As Stefan Tilkov explains in his 2016 post Why I hate your Single Page App,

Maybe your single page app is different, but the ones that I know break most of my browser’s features, such as the back and forward buttons, page refresh, bookmarking, sending a link, or opening a link in a new window or tab.

They offer no way to link to something that I look at. (Oh, I know there are exceptions to this rule, but they typically require effort — a lot more than many developers are prepared to invest).

They are bloated and slow to load, even though the actual information they display and the interaction they offer is very simple.

To be fair, Single Page Applications do try to address these concerns using various techniques, but that’s a big topic in itself. Some SPAs are even a pleasure to use, especially if implemented well. The best example of a flawlessly executed single-page application is Ghost, the blogging platform I use to write and publish my blog.

However, after working with and using many poorly implemented SPAs, I couldn’t agree more with Stefan. I was so frustrated with the frontend and the onslaught of JavaScript frameworks over the past decade, I almost gave up on JavaScript and tried to stick to the backend, until I came across Hotwire.