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, slow and fragile experience. Furthermore SPAs are much harder make.
In this article, I’ll explain why that is. But before I do let’s make sure we’re on the same page about what SPAs actually are.
# What’s an SPA?
You might think about MVC, data flow and client-side templating when you think of SPAs. But they‘re not the defining characteristics of SPAs.
In actual fact, you can use all those things to create rich, but more traditional ROCA-style sites.
# 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.”
- storing pages in memory, local storage, client-side databases or cookies.
- working out when to retrieve the cached pages and when to invalidate them.
For (2) there needs 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 which is not achievable as far as I know.
# 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, our code needs 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 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 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.
The code needs to handle all of these cases.
To let users cancel requests, we need to put a custom cancel button in the UI – which isn’t desirable.
# 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 this needs reimplimenting from scratch.
# 5. Search engine ranking
Search engine optimisation is usually an afterthough when building SPAs. But retrofitting this is difficult and costly.
Creating a separate dedicated server-rendered site for search engines is wasteful and means having to maintain a lot of extra code.
With a traditional ROCA style site we get this for free.
# 6. Loading CSS and JS
# 7. Analytics
Analytics tools track page views by default — you just add the analytics code to the page.
But SPA pages aren’t real pages which means additional logic needs to be written to make analytics can track pseudo pages when they get rendered.
# 8. Automated functional testing
Like the previous point, automation tools like Selenium know when a page has loaded.
But automation tools don’t automatically know a page has been loaded with AJAX.
THis makes tests more challenging to write to handle timeouts and they’ll be slower to execute.
# 9. Memory leaks
As SPAs don’t load pages, the page may 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
The browser’s 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 slows users down further.
The result of which is a blank screen and leaving users to refresh the page or give up.
# 12. They’re probably slower
SPAs are very likely to be slower than server-side rendering because:
- loading and rendering a page with AJAX is usually slower
- extra coded is needed to fix the issues above
“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.
Many people think SPAs provide faster and better experiences but in reality they create a slower, unfamiliar and inaccessible experience.
Worse is that they’re harder to make in the first place.
And it‘s not just me – Twitter, Lifehacker and Delicious went back to more traditional architectures for these reasons.
You can read more below:
Sign up to my newsletter
I’ll email you once a month on nailing the basics, avoiding complexity and making things that work for everyone.