
Why I hate your Single Page App - ausjke
https://medium.freecodecamp.org/why-i-hate-your-single-page-app-f08bb4ff9134
======
trjordan
Why I hate your classic HTML app:

\- Every click is a full page load, and you still didn't manage to get caching
right, so it takes 2 seconds to load.

\- When I have multiple tabs open, your badges and notifications fall out of
date, because you never poll for updates.

\- If I mis-enter information into a form, your error handling forgets all my
information and I have to re-enter it.

\- You forgot to update the styles on that rarely-used page, and now it's got
half the new CSS and half the old CSS and the point is the header runs halfway
down the goddamn content in Times New Roman.

I get it, there are problems with SPAs. But this perfect land of one-page-per-
link has real usability problems if it's not implemented properly, and there's
a lot of maintenance overhead associated with a sprawling mass of transcluded
templates. If we're going to criticize an architecture because it's easy to
poorly implement, I don't think "ROCA" or whatever we're calling it has any
meaningful benefits over SPAs in the general case.

~~~
cpburns2009
Since we're talking about poorly implemented features.

Why I hate your SPA:

\- If I click on a link, I receive no indication that I actually clicked a
link, then 2-10 seconds later the page abruptly loads. Sometimes the page
doesn't load at all.

\- I cannot tap and hold a link, wait a second for the pop-up menu, and open
the link in a new tab because the link isn't actually a link. It's implemented
in JavaScript.

\- The back and forward buttons don't work as expected because either history
isn't maintained or it's shoddy (scrolling _should not_ be a history event).

\- The refresh page button don't work as expected because it resets you to the
beginning.

~~~
aaron-lebo
Just to be clear, that _is_ a poorly designed SPA, none of that should be
happening and is easy to avoid.

~~~
cpburns2009
That is absolutely true, but I've seen it enough times to be annoyed. Also,
the grand parent post was about classic HTML apps which were poorly designed
with issues that should be easily avoidable.

------
ordinaryperson
> 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.

My SPA is different -
[https://www.seasonalfoodguide.org](https://www.seasonalfoodguide.org).

Browser back button works like normal.

Each screen has its own discrete URL, so you can share links, refresh,
bookmark or open in a new tab, just like any other website.

I think the criticism here is misguided. The problem is not with SPA as an
architecture, it's with SPA devs not implementing features that end users are
accustomed to on a website. They can all be added, it just takes effort.

The biggest valid criticism to SPAs IMHO is the initial site load. There are
ways to mitigate (CDNs, progressive loading, compression, etc) but pound-for-
pound SPAs probably have longer initial load times on average for the first
page than a vanilla HTML site does.

Once it's loaded there's no faster way to traverse a website, IMHO.

~~~
strken
> My SPA is different -
> [https://www.seasonalfoodguide.org](https://www.seasonalfoodguide.org).

This app is a good example of one of my pet peeves: ctrl-click doesn't
reliably open links in a new tab.

~~~
com2kid
Middle clicking works great, so I am happy! Mice need at least 5 buttons
anyway.

Right click and open in new tab also works. I always forget about ctrl-click
since I never use it, odd that it doesn't work given how well everything else
does!

~~~
mnarayan01
Middle-click is not working for me either in Firefox.

~~~
com2kid
Works fine in both Edge and Opera (Hah!) on Windows 10. :)

It doesn't work in Internet Explorer though. No FF on this machine to test out
unfortunately.

------
cletus
+1000

The biggest things for me are probably the excessive amount of resources used,
the long load times, how hard it is to get things "right" (like not breaking
the back button) and links taking awhile to load because we have to load your
stupid SPA (if they work at all).

SPAs did win out big in one area though. On mobile. Except on mobile they're
called "apps". As much as many HNers like to chafe against native mobile
development as they yearn for the open standards of the Web, native apps have
basically "won". Users love em.

I guess that leaves desktop.

I do wish more people asked "does my Web presence need to be an SPA?" or even
"will it benefit significantly from being an SPA?" because I feel like the
answer more often than not is "no".

~~~
Skinney
How hard it is to get things right? It's not hard at all. It's builtin with
frameworks like Ember or Angular, and for React you got react-router which
does things correctly by default. It's just bad programming. I don't even
understand why people would make an SPA without a url-router. Doesn't that
just make development harder/more anoying?

Why would links take longer to load in a SPA? CSS, Javascript and the like
should already be downloaded, there should be much less networking involved.

Also. My SPA's come in at around 120-130kb minified (no gzip). That's about
the same as "pure-html" sites which include jquery.

I do agree with your last point though. Pure content sites, or even
"mostly"-content sites, is probably better off with backend generated html.

~~~
bpicolo
> My SPA's come in at around 120-130kb minified (no gzip).

react-dom is just a touch bigger than that alone, fwiw

~~~
Skinney
I know, react is pretty big. Preact is great if using Javascript, otherwise
Elm is pretty awesome as well.

------
_sdegutis
One big downside of SPAs the author didn't mention is the chain reaction
effect I wrote about last year[1], where if you start to implement one
browser-native feature in JS, it breaks other browser-native features, and it
begins a chain reaction where you basically implement the whole site in
JavaScript, and the result ends up being noticeably worse than if you had just
stuck with native browser features from the beginning. It's not necessarily
specific to SPAs, but it's definitely a very common problem I see with them.

[1]: [https://sdegutis.com/blog/2016-03-21-why-i-dont-use-
clojures...](https://sdegutis.com/blog/2016-03-21-why-i-dont-use-
clojurescript/)

------
tabeth
None of the things described here are _inherent_ to single page apps. Ember
(with Ember Data and proper routing), for example, solves most of the issues
he brings up (back button not working, failure to link to individual items) by
convention.

~~~
coldtea
> _None of the things described here are inherent to single page apps._

Does it matter though, if they are still all _prevalent_ on single page apps?

~~~
tabeth
I think so, if only because the discussion should be surrounding best
practices and following standards, as opposed to a sensationalist notion that
single page apps should be abandoned in general.

------
brootstrap
Some of this hits home for me. I work on the WAY DEEP backend of one of these
'modern single page apps', so dont really care about the REST apis or UI/UX. I
will say our actual website is a nightmare to use and I attribute a lot of it
to (A) mgmt demanding bad UI/UX on short timeframes(B) front end folks having
the power to write butt loads of JS code to achieve said goals with no thought
to system wide architecture / integration. We have so much shit happening each
time you click to a different part of webapp, we seem to have hit the messy
phase of a codebase where you cant change one part of the site without
breaking something else in a totally different section of the codebase.

to be fair though, as with everything there are pros and cons. Once i learned
to deal with some of complexities and crazy UI/UX, using our web app is like
driving a spaceship and it does work pretty fast considering all the data
getting lifted, html getting rendered etc.

~~~
tigershark
"you cant change one part of the site without breaking something else in a
totally different section of the codebase" Welcome to the feeling I had in
2005 in a Java swing "application". And I guess lots of people felt the same
even before..

------
tyrw
Answer: "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."

~~~
sova
Yeah, these are problems. 2017 and the browser still doesn't know what the
javascript is trying to accomplish

------
derekp7
I really hate articles that have a large fixed header at the top, that causes
the next few lines of text to be hidden when I hit page down. Something
something glass houses and throwing stones.

------
gorpomon
I half way agree here. Too many things are SPA's that don't need to be. An
internal tool used by < 1000 people? Maybe let that stay server side rendered.
A cutting edge app that promises a new clean way to
bank/farm/hire/cryptowhatever, then please embrace SPA's and PWA's. The reason
we have a glut of these SPA's is because we have devs, designers and product
not recognizing context. Some things don't need to look or feel cutting edge.
The real tragedy here is that I've seen companies burn thousands on SPA's when
they could have had one front-end on their API team make it server side
rendered.

------
jmartens
What you hate is just bad design and programming. All these things can be
handled in an SPA.

------
paozac
Most websites get little benefit from using a SPA architecture, and the
negative aspects are significant:

\- deploy headaches

\- the infamous JS fatigue

\- debugging (minified code and nested anonymous functions make it painful)

\- troubles with content blockers

I guess we'll have to wait a few years until the JS/SPA ecosystem will become
more mature and find good solutions to these annoyances. Until then I'd gladly
stick with rails, django & friends, both as a developer and as a user.

------
twobyfour
This. A thousand times this. And if you do it for a content site, you deserve
a special place in hell.

~~~
Skinney
That place reserved for child molestors and people who speak at the theatre?

------
darkstar999
Can someone link to popular sites that do things he's criticizing?

------
oblib
He makes some good points. There are good reasons and uses of the tech in
SPAs, for example, I show previews of documents made with forms by hiding the
form and rendering the document, but on a blog app I made where I did the much
the same thing I made a button that linked to the article so users could find
it easily. The "go back" button didn't work to reopen it though and I suspect
search engines wouldn't have known what to do with it.

------
5trokerac3
Most of his argument is negated by using routing and route parameters.
Generate a unique ID for all data points and any page can be linked to and
will be in the history.

------
vanderZwan
> _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._

That reminds me: if anyone out there has any advice how to make AppCache play
nice with JavaScript-based routing solutions (say, react-router), please let
me know.

~~~
marksomnian
Are you using AppCache for compatibility reasons? If yes, my condolences. If
no, just use Service Worker. If you don't want to write it yourself, use sw-
precache.

~~~
vanderZwan
I _was_ trying to support Safari, yes. But maybe I should just give up on
that.

~~~
marksomnian
Safari has ServiceWorker in active development. It'll take a while, but it's
sooner than one would think.

------
seanalltogether
Web browsers were designed to deliver stateless documents to users.

Modern users want content delivered to them in a personal, rapid,
contextual(stateful) manner

Fight.

~~~
sidlls
> Modern users want content delivered to them in a personal, rapid,
> contextual(stateful) manner

Is that actually true? Maybe it's that web developers want to deliver content
in this way and try to do it with the browser instead of a native application
more fit for purpose and they don't actually give a damn about what the user
wants.

~~~
com2kid
> Is that actually true? Maybe it's that wev developers want to deliver
> content in this way and try to do it with the browser instead of a native
> application more fit for purpose and they don't actually give a damn about
> what the user wants.

Remember old forums that made you load each and every reply in a thread?

Compare that to Reddit which allows for collapsing and expanding of threads,
and for async loading of reply chains that go on for too long.

Being able to open-in-place media users link to was a huge reason for the
uptake of Reddit Enhancement Suite, now, a feature built into Reddit. Upvoting
not taking users to a new page or reloading the page (compare to how Slashdot
used to do it!), all these features involve maintaining state.

Same thing for most bug tracking apps. If I am triaging a list of bugs, a SPA
is the way to go, I don't want to spend more time on page loads then on
marking triage status.

------
vilmosi
>>> 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

All these concerns assume HTML 5 history api doesn't exist. It does and SPAs
can do all that.

------
atanasb
A very bizarre article I feel.

Stefan identifies common pitfalls or shortcomings of most single page
applications such as:

1\. Bad performance because of too many operations

2\. Breaking browser navigation buttons

3\. Not having unique links/anchors to in-page content.

While there are in fact multiple ways of bringing focus and solving these
problems the authors suggests that simply ditching SPAs for native toolkits or
backend/frontend system is the way to go.

While switching away from SPAs might mitigate the problems listed above - it
will also present new problems that developers have to tackle - or simply
spend time on.

The main problem here is how hard the problems he describes are to deal with
in current frameworks I believe. He has one thing 100% right - bringing
attention to those problems is the right way to go.

------
js8
Lot of SPAs I have seen also reinvent the desktop. They have their own tabs
and dashboards. And they do it badly - no shortcuts, no integration with the
file system..

------
BalanceMarx
I've always liked JQueryMobile because it breaks so few things. I haven't
tried some of the newer alternatives.

~~~
frik
JQueryMobile was the slowest ugliest thing back in 2011-13 timeframe. Faking
the iOS1-6 UI controls even on Android - no words.

------
Techonomicon
Come on, this is clickbait as it can be with the title and the first line of
the article, that's what I hate.

------
vbuwivbiu
but that's the point: an application isn't a webpage. An app doesn't have a
concept of back and forward, it has undo & redo. It doesn't need refreshing
because it's syncing with the server by websocket. It doesn't have location it
has state.

------
skrebbel
Use a decent router. Single Page App ecosystems have been festered by mediocre
routers that make doing stuff like this hard, where there's no need to be.

This is the design our team likes to follow, I haven't seen it documented
anywhere (but I doubt it's new), so I'll write it here.

Essentially, we try to replicate traditional server side MVC thinking on the
client side. Decent server side rendered apps that don't have the problems
mentioned in the OP's post usually follow RESTful principles to some extent.
This means that what you see on a page is a pure (ish) function of these
things:

    
    
        * The parameters in the URL
        * The state of the database
    

And nothing else. Translated to the client side, it means that you want
anything the user sees to be a function of:

    
    
        * The URL
        * The state of the model layer (or the flux stores, whatever)
        * Addendum: 100% of the model layer is an 
          eventually-consistent subset of the database
    

We use one exception to this rule: unimportant state is allowed to be right in
the view (we use React, so that's component state). Stuff like "is the
dropdown menu expanded" or "which of the items in a list are selected" is
neither in the URL nor in the model layer (because we won't sync it back to
the database). The rule of thumb is "if the user refreshes the page, is it a
problem if this data is lost?". If the answer is "no", we can make it
component state, as close to the action as possible (so not in the root
component usually).

All of this combined gets us a lot of stuff for free. For example, all our
modal dialogs, and even "is the menu shown" is addressable from the URL. This
might feel like overengineering, but it gets us lots of stuff for free.

For example, users on mobile phones expect to be able to close a modal or a
menu by hitting the hardware back button. We get this for free, because when
the user does an action that causes a modal to show, we redirect to some URL
like example.com/wherever/?someModal=1. (all using the history api). Router
picks it up, modal is shown. Model layer is not touched, this is 100% view
layer work. Then, when the user hits "back", the browser restores the URL to
example.com/wherever, router picks up the change again and the view renders
the same page but without the modal.

We get all the usual browser features for free simply by following basic REST
ideas. Don't put URL stuff in your stores. Don't put non-backend-synced stuff
in your stores (just like you wouldn't put important state in your sessions in
server side rendered apps). Put everything that matters in the URL.

Any routing library that encourages you to sync URL stuff into your model
layer is, IMO, wrong by design.

------
Etzos
This looks like it needs a (2016) tag in the title.

------
pavlakoos
This post is soooo old...

------
j4ybee
Why I Hate your Strawman Article

