The disadvantages of single page applications

Many people in the web community believe that SPAs (single page applications) give users a superior user experience.

But most of the time, SPAs give users an unfamiliar, inconsistent, fragile experience. Not only that, but SPAs are much harder and costlier to design, build and test.

In this article, I'll explain why that is. But first, let's define the meaning of a SPA.

What's an SPA?

You might associate MVC, data flow and client-side templating with SPAs. But these things are not the defining characteristics of an SPA. In actual fact, you can use all of them to create rich, but more traditional ROCA-style sites.

SPAs can be defined as applications that handle routing or navigation using client-side JavaScript. In other words, instead of letting browsers handle the browsing, the application code hijacks it in order to change the URL, make requests and render responses itself using JavaScript.

Using JavaScript to do the very thing that browsers are made for and already does for free is the cause of all the problems.

1. Going back and forward quickly and reliably

Browsers store history so that pages load quickly when the user clicks back. Daniel Puplus explains in Building Single Page Applications that:

“When a user presses the browser’s back button they expect the change to happen quickly and for the page to be in a similar state to how it was last time they saw it.

“In the traditional web model the browser will typically be able [to] use a cached version of the page and linked resources.

“In a naive implementation of a SPA hitting back will do the same thing as clicking a link, resulting in a server request, additional latency, and possibly visual data changes.”

To give users the expected and fast experience, we need to emulate the same native browser behaviour using JavaScript which involves:

  1. storing pages in memory, local storage, client-side databases or cookies.
  2. determining when to retrieve the cached pages and when to invalidate them.

As part of (2) there will need to be logic to work out whether the user is changing the URL manually—by clicking a link or typing a URL directly in the location bar. Or by pressing the browser back or forward buttons. This is not achievable to my knowledge.

2. Scroll position

Browsers remember the scroll position of pages you've visited. Daniel Puplus, again, explains how SPAs cause trouble here:

“Lots of sites get this wrong and it’s really annoying. When the user navigates using the browser’s forward or back button the scroll position should be the same as it was last time they were on the page. This sometimes works correctly on Facebook but sometimes doesn’t. Google+ always seems to lose your scroll position.”

To fix this, we have to write code to store, retrieve and apply the correct scroll position when the user navigates back and forth.

3. Cancelling navigation

When a user clicks cancel, or clicks a link, the browser will stop any in-flight requests.

SPAs retreive entire (data for) pages using AJAX. So there could be several requests in-flight. The first request could finish last. Or, a user could click (and therefore request) the same link twice.

This is problematic because its inefficient, will use up people's data unnecessarily and cause visual glitches as subsequent requests finish that should have been cancelled.

Again we need to write code to handle all these use cases. And to let users cancel requests explicitly, we need to put a custom cancel button on the interface which is undesirable to say the least.

4. Handling unsaved changes

In a traditional web application, we can warn users of unsaved changes using the beforeunload event. But SPAs don't navigate, which means this event won't fire. So we have to reimpliment this ourselves from scratch.

5. Search engine ranking

Search engine optimisation (SEO) is usually an afterthough when building SPAs. But retrofitting this is difficult and costly.

Creating a separate dedicated server-rendered site for search engines to access is wasteful and means having to maintain two separate codebases.

With a traditional, ROCA style website, we get this for free.

6. Loading CSS and JS

As an SPA grows in size, loading all of the application's assets on load will be especially slow. This can lead to the conditional loading of CSS and JavaScript.

But script loaders contain hacks, slow down development and reduce reliability.

7. Analytics

Analytics tools track page views by default—you simple add the analytics code to the page and that's it. But SPA pages aren't real pages.

This means we have to add logic to the application to make sure the analytics tool picks up new pages being loaded in without a refresh.

8. Automated functional testing

In relation to the previous point, automation tools like Selinium know when a page has loaded. But automation tools don't explicitly know a page loaded with AJAX has loaded.

This means tests will be more long winded to write (by having to handle timeouts etc) and they'll be slower to run.

9. Memory leaks

AS SPAs don't load pages, the initial page will stay open for a long time. This increases the chance of memory leaks which can cause the browser to crash and battery powered devices to drain quickly.

10. Loading indicators are inaccurate

The native browser loading indicator provides an accurate, predictable and familiar experience to users across all sites the user visits in their browser.

As SPAs use AJAX to render pages, we need to create a custom loading indicator from scratch. Besides the extra work, custom loading indicators tend to be inaccurate and unfamiliar.

This can cause users to click the link again which creates a frustrating experience.

11. It's going to fail

JavaScript can fail for many reasons. And most SPAs aren't written using progressive enhancement.

As a result, when there's a failure, the result will be a blank screen. Putting the onus on the user to refresh the page, use another browser or simple leave.

12. They're probably slower

SPAs are very likely to be slower than server-side rendering because:

“Fun fact: it takes a Moto G4 about 15.66 times longer to evaluate 2.1MB of (decompressed) JS than it does to decode a 10MP image.”—Harry Roberts

13. They're not accessible by default

Read One-page-applications are not accessible by Craig Abbott.

14. They just don't feel right

Read Why I hate your Single Page App by Stefan Tilkov.

Summary

So many people think SPAs provide faster and better experiences but in reality they create a slower, inconsistent, frustrating and inaccessible experience.

And to make matters worse they are actually harder to design, build and test. And I'm not the only one to have experienced this.

Twitter, Lifehacker and Delicious reverted to traditional architectures for these reasons which you can read below:

JavaScript is not going to be better at browsing than what browsers are made for (browsing!). Instead, we can create just as rich and better experiences by following the rule of least power and ROCA style websites.