110 comments

[ 2.5 ms ] story [ 186 ms ] thread
> broken “open in a new tab” behaviour – people like to handle links in onClick handler, and browser can’t recognize it as a link (even if the majority of the links are valid, sooner or later you’ll encounter a non-link “link”)

This one annoys me the most, but I will say an analogous problem is fairly common on non-SPA web sites, where reloading a URL doesn’t work as expected.

That's usually just a lack of basic engineering practices common to well-implemented SPAs.

All requests below the SPA's root should be forwarded to the SPA root, which appropriately then routes the request to the proper views and controllers.

Proper usage of resource IDs in these URLs allows a newly initialized application model to populate and serve the appropriate content for the appropriate views.

The point is that browsers already have built-in code to interact with links and such in a predictable and straightforward manner, and your suggestion that "a lack of basic engineering practices", implying all SPAs need to reimplement that functionality, shows just how absurd the situation is.
The fundamental difference between a SPA and traditional website is that the routing and compositing of views is generally handled by the client rather than the server.

It doesn't make sense to call something that doesn't respect that design a SPA. A poorly implemented SPA is what I would call that.

Zero contrary posts pointing out where I'm possibly wrong but them vote-brigading remains.

Hackers News '18, folks.

Most SPA's don't, because most frameworks have some built-in functionality for this.
There's nothing to reimplement. Browsers navigate based on URLs, so if the URL for a page in an SPA isn't enough to load the full state on a fresh pageview, then it won't work.

So it's absolutely about proper engineering to make sure pages have working direct URLs rather than just relying on other navigation while the app is already open.

Sure there’s something to reimplement. Ensuring that changes to the view state are represented in the URL bar isn’t trivial. Should a popup dialog be reflected in the URL state? Should a confirmation prompt? What about browsing a hierarchy of menus?

With web pages as documents that only use JavaScript to “decorate” things, you get this for free. And it’s likely aligned with what users expect.

I really don't understand where you're coming from. SPA routing is a solved problem. There are countless modern solutions that are not only trivial to use but offer bonus functionality over traditional approaches, such as isomorphic routing or controlling the state of individual components and elements with routes instead of entire pages.

> Should a popup dialog be reflected in the URL state? Should a confirmation prompt? What about browsing a hierarchy of menus?

These aren't examples of problems with SPAs, they are examples of things that do not cleanly map to URL routing in general. You could ask all of these same questions of a normal web page and they would have the same answers.

Terms like "solved problem" and "modern solutions" set off my BS detector. Doesn't the existence of countless solutions, rather than relying on built-in browser behavior, imply that it's not a solved problem?

No doubt single-page apps have their benefits, but there's an awful lot of new hotness kool-aid being passed around. The JS ecosystem is still suffering heavily from the inner platform effect.

This is a strange comment thread as it seems everyone is talking past each other.

Browsers can only navigate via URLs. Traditionally these pages are rendered completely on the server but SPA's can just as easily load the appropriate page based on the URL, it's just done on the client and requires routing to be setup.

Whether it's actually setup like that is up to the developers to do, as many don't use routing for all inner pages. If they don't put in that effort then there are no URLs to navigate directly and thus there is nothing for a browser to do to open a new window/tab. Routing is a solved problem and is purely about implementation.

> Doesn't the existence of countless solutions … imply that it's not a solved problem?

Is this a serious question?

It seems like you're letting a bit of bias against the JS ecosystem invade your thought process here. There are countless solutions because they range from generic, such as a simple routing helper, to deeply integrated, such as react-router.

> rather than relying on built-in browser behavior

You mean the built-in behavior of navigating away from the current page? The single page application?

> SPA routing is a solved problem.

Is it? I'm new to web development, so I don't understand your statement. E.g. does any SPA framework offer support to the stop button? I've been learning Vue and Mithril recently. Apparently, both libraries/frameworks have no support for the stop button, so you cannot use the browser's stop button to cancel routing/loading stuffs after you clicked on a link.

JS devs happily call it a "solved problem" after they completely reinvent it after every release of their framework du-jour. It's solved until it's not, then you solve it again.

Is react-router stable yet? I looked at react a year ago and every tutorial out there used outdated syntax because they revamped the whole thing. The last angular project I worked on tried 3 different approaches through the life of the project.

The point is, with web pages as just documents that come to the browser fully-formed, there's no need to ask the question any more: the URL is the path to the document, and you get a new URL when you get a new document. There's no need to make special cases for popups/etc since the answer is always "no". You just don't do routing logic on the client at all.

Edit: just to be clear about what I'm advocating, if you embrace the document-style non-single-page model, you simply don't worry about view state or how it's routed/represented: any javascript code you do write (jquery etc) doesn't need to touch it, and any "real" hyperlinks that load a new page from the server naturally affect the view state normally.

One path to a SPA that supports all those features without implementing them, and is also "progressive" (i.e., the first request comes from the server so that it's fast even on mobile, and search engines and non-javascript browsers are supported) would be:

- Implement a non-SPA web app in Node.js

- Include (parts of) the server-side code in a Service Worker. That way, after the SW is installed, the SW would handle requests instead of the server.

- Polyfill the missing parts. For example, you could polyfill the database to store updates when offline and sync them later.

Maybe you could make a framework where you can share code between Node.js and the Service Worker, similarly to how you can do server-side React today.

One of the ways that I prefer to judge a JavaScript framework is (1) what is the minimum payload to use it, and (2) how nicely does it play with a hybrid app?

In practice I’ve found VueJS does pretty well in this regard. Rather than build a full SPA I can sprinkle a few components here and there on pages that are highly interactive. The rest of the mostly static screens on my app are perfectly happy to be rendered from the server.

It can be hard to strike the right balance between developer friendliness (ie maintainability and extensibility) versus user experience (ie speed and backwards compatibility) these days, but as always it’s important work to deliver the best user experience we can, and I agree with the author that SPA are not always the right choice in this regard.

>Rather than build a full SPA I can sprinkle a few components here and there on pages that are highly interactive

In practice, I've found "hybrid" apps hard to pull-off. In my experience, the question becomes, where do you draw the line?

Take the simple/common case of presenting a list view. From the list, you want to allow the user to click to view details, which you then present dynamically--maybe in an overlay. It's a great user-experience. Everything pops, the user can easily return to the list view without a full page-load, etc.

But, you now have a details view that is not reachable directly via its own URL. So, you use the framework's routing capability to assign one. Now, things are getting weird, because you're routing a dynamic view on top of a server-rendered one. You'll likely end up finding that you'll have to route the server-view as well for general navigability. And, you also have to account for people hitting the details URL directly (i.e. render the proper underlying server view, then let the client route to the dynamic URL).

Not to mention the back-button.

All manageable, of course. But, it gets messy to maintain such a hybrid approach. By the time you've integrated the routing, etc. the question becomes why hybrid? Why not full SPA?

If your app is super-simple wherein you're just doing the tiniest bits of dynamic stuff and you don't need things like first class URLs, navigability among dynamic content, etc. then, yeah, maybe. But, that's not really a hybrid-SPA solution because there's no SPA there.

In fact, I'm not sure there is a such thing as "hybrid-SPA". By definition, seems it's either a SPA or it's not.

> In fact, I'm not sure there is a such thing as "hybrid-SPA". By definition, seems it's either a SPA or it's not.

I'm open to hybrid being defined as two possible things: a regular SPA with server side rendering (SSR on manual refresh and first visit). Nextjs for react, Nuxtjs for VueJS, angular universal. I think OP was talking about the other definition of hybrid.

The second definition is for when your team prefers or is only trained in or is maintaining codebases in the legacy MPA style, typically similar to Rails+jQuery. When you need a specific div element to have advanced UI components and a jQuery plugin didn't fit the needs, the answer was "not happening". VueJS showed up and changed this to "can budget finite dev hours and willing to maintain", as it had good tutorials for assuming you wanted a small widget instead of a full rewrite to SPA. Do this enough times, and you have a hybrid. Now you have enough SPA-ness that you can be satisfied or you can plan a multi-sprint "convert the rest to SPA" project.

I have a hybrid app using reactjs. It's mainly used in very interactive/dynamic sections. It's used in pages where we want to present different data display based on device like in desktop we display grids but in Mobile is a single row list.
One thing that doesn’t get mentioned is that writing an SPA feels more like programming.

Writing jquery feels like idk...not quite like programming.

It’s a lot more like writing a native mobile app, that’s for sure. You manage data and state with a much more long-term mindset. A bad line of JS is equivalent to a crash if it halts the whole SPA from working and requires a refresh.
I'd about say the opposite.

Organizing all your jQuery into meaningful classes and keeping the whole thing organized and orchestrated is very much the essence of programming. It's a rare skill (as a trip through many large jQuery code bases reveals).

Filling in some templates causing magic to happen behind the scenes on the other hand, not so much.

That being said, 1) are we interested in feeling like programmers or in pumping product? 2) if "pumping" is the answer, best tools depends on what is being done. All in favor or SPAs (when needed), but no, they aren't cooler than jQuery and are often big fat pigs that just shouldn't be used in that situation.

>I'd about say the opposite.

>Organizing...into meaningful classes and keeping the whole thing...orchestrated is very much the essence of programming

>Filling in some templates causing magic to happen behind the scenes on the other hand, not so much.

I'd agree and add that the different perspectives might be in large part due to the shift in programming away from procedural/code to declarative over the last decade or so. That is, if you started in coding over the last ten--and especially five years--you're much more likely to think of programming as declarative as much as code-oriented.

And, the shift towards frameworks is probably the biggest driver of the declarative trend itself.

lol you caught me, I'm old.

I'm all in favor of what's fast and easy. So many jQuery messes have almost given me PTSD. So not knocking frameworks in any way. It's just weird to me someone would suggest using them is "more like real programming". No, it's more like one of those paint by number kits rather than a blank canvas and some paint. Of course many people are going to get better results with the paint by number kit, but it isn't more like "real" painting. It's less like "real" painting. And, if you reach for a paint by number kit when all that's needed is a few red dots you are messing up and ought to learn the craft naked a bit for such situations. jQuery isn't a paint by number kit. More a set of stencils and brushes you are free to make as big of a mess as you like with.

>lol you caught me, I'm old

Ha! Only because I can totally relate my friend. Been in the game a while myself. That really is how I can identify with what you're saying.

And, you know what? We're right! Adding an attribute to an HTML-like component tag is not programming, no matter who insists it to be so. That's not to say there's no value to such approaches, but it still doesn't make it coding.

Was talking to another coder friend a while back and we agreed the game has changed: it's more about integrating pieces into a whole than writing swaths of logic. In other words, "coding" is now more assembling than construction.

It's possibly (but not categorically) more productive and it may represent "progress" by some measures, but it is still ironic to hear that referred to as programming over actual programming.

I've worked on a number of SPA's over the years and I always run into the problem of getting my team to give a shit about performance. "We're not Google," they protest. Frankly for a lot of people it's the trade-off of slow client performance for development velocity. It's much easier to just throw on another state for new functionality than it is to consider what parts of the page can be static and how they can be rendered.
Surely if you can't produce an SPA with equivalent or better performance than a more traditional architecture then - don't build an SPA.

Or even better use a simpler solution that gives me 80% of the benefits of an SPA: Turbolinks, PJAX, intercooler.js or even a light sprinkling of good old AJAX.

Does anyone remember "progressive enhancement"?

Perhaps the most simple and trasparent solution to seamless navigation: http://instantclick.io/

As long as your backend is fast enough, it feels like navigating a SPA.

See, "we're not Google" should actually mean that you care about performance more. Google can throw millions of dollars worth of infrastructure into making an app go marginally faster. Whereas, all you have is brainpower before you deploy or ship. And it doesn't take that much more brainpower to get big increases in client performance when you're starting from not-optimized-at-all. The marginal payoff is larger and the marginal costs are much smaller.
Many of these pitfalls can be avoided with intelligent server side rendering, which includes the router on the server, so no using client-only “#” URLs. But, that adds another significant layer of complexity to application development.
Half-expecting this article to itself be SPA, and was pleasantly surprised that it isn't.

I agree completely with the author; there's some things (games and such come to mind) which certainly deserve to be SPAs, but the majority of the time it's a horrific waste for every single visitor to have to process MBs of data just to display a few KB of text and hundreds of KB of images (at most). Why? Just so developers can show off that feeling of how awesome they are for using some incredibly complex framework. That, and the ridiculous rate of churn, are probably what most irks me the most about the whole web development community (and why sites like HN appeal to me so much.)

I'm not sure what's responsible for this "love of bloat", but IMHO we should be teaching developers how to do more with less, and not the complete opposite as seemingly happening today.

> Why? Just so developers can show off that feeling of how awesome they are for using some incredibly complex framework. ... I'm not sure what's responsible for this "love of bloat", but IMHO we should be teaching developers how to do more with less, and not the complete opposite as seemingly happening today.

I think you're misplacing the cause into developers. Developer's want to use the SPA framework because certain magnitudes of "application like UI" become maintainence nightmares for teams who stick with jQuery or use youmightnotneedjQuery.

The reason they end up bloated or with random framework-supported elements broken (back button, etc.) is from what I call MVP culture. AIM and IRC were perfectly fine in the early 2000s, but instead of upgrading them for 2010+ they were abandoned or stripmined of value (Skype). Now we have slack, discord, flock etc.. releasing MVPs. Except apparently, they are perpetual MVPs.

Many industries are encountering this. Developers at large are not permitted to rewrite in native languages, optimize any non-blocking performance issue, fix bugs that don't affect the bottom line. Everyone's trying to disrupt an industry so they can vendor lock in high profit rents. When we finish switching from typescript to reasonML and decide to switch from reasonML to Nim/kotlin-native, MVP culture will still be there to tell developers not to fix the broken back button.

I always thought the decision was:

- Content site = NOT single-page-app

- Application = single-page-app

Maybe there's more of a gray area between content sites and applications these days, but I think it's still pretty obvious: If most of the user's time is spent reading content, it's a content site.

That's a good starting point. I'd drill down even further and ask "what does the user do with the application?"

If the user needs to look at multiple screens at a time (e.g. like a mail client or something of similar complexity), then they're a candidate for an SPA. If the user does not need to do that, the app is probably simple enough to not be an SPA.

I work in ecommerce and I feel it’s somewhere in between. We need to build for seo optimizations for the category/product experiences yet there is a lot of application like intersections, especially on the category filtering and the product sku selections. Quickshops, In store pickup modals, user specific recommendations trays, add and edit reviews et all. Different caching for server render at the edge vs personalized components adds another layer. Being able to serve with a shared routing scheme both client side (for improved performance) and server side for faster initial page load and seo on non-Google crawlers is a tough problem. Especially when you add in client hydration of the redux store. That parse time is a real killer on mobile. You add in service workers and prefetching and the complexity ratchets up further. The other issue we deal with is marketing pixels and trackers. But that’s another story. There is a ton of complexity in building a highly functioning ecommerce site.
Is it really worth the trade-off? I remember eCommerce sites trying to do similar levels of interactivity with Flash too. I just think, for a catalog site, it seems like you're trying to swim upstream. Especially on mobile.
The problem is even content is becoming functional with interactive charts, infographics and figures, videos, media, filtering, sorting - then the site will eventually need comments, ads, subscribing, favoriting, upvoting, login, lazy load next article, infinite scroll, etc. Yes, a pure content site shouldn't be an spa, but how long can you survive running a pure content site? Information is complex and the web allows us to communicate it more richly than the static 2d representations of old.
What are static 2d representations?

You can do everything you mentioned without an spa just fine. Plenty of content sites (the majority, actually) survive just fine.

Well he’s taking about a hybrid. Each of your pages are essentially little applications on their own.
The problem is, this can all be solved with just a little bit of javascript to make interactive charts, infographics and figures, videos, media, filtering, sorting - then you can still serve static comments, ads, subscribing, favoriting, upvoting, login.
> I always thought

and you were right, although, with things like Angular Universal and initial server side rendering of SPAs in general, are changing this.

The problem with SPAs in the sort of cases that the author is talking about is that people don't think clearly about what requirements they are satisfying when writing a new one. If your app actually needs to switch between various screens without a refresh so your users can most efficiently get their work done, then yes, by all means, make an SPA. That requires knowing clearly who your users are, what they want to do, and what constraints they are under (e.g. if they all work on desktops with good internet access, maybe it doesn't matter that your app is bloated and slow on mobile). I think most people don't do that thinking step first. They want to play with the new shiny, either as a sort of fun or so they can add it to their resume.

This I think is made worse by the unparalleled decadence in which the modern, first-world developer now lives. It is absolutely excessive to have to download 2.6 MB just to show a blog or some simple textual information, but thanks to broadband everywhere and terabyte hard drives, nobody under the age of 30 who isn't working in embedded systems thinks about this anymore.

"Stop writing only SPAs" is advice in the same way as "stop making only left-hand turns". This article stops short of convincing me to stop biasing towards SPAs because it appears only to reiterate known challenges about SPAs and calls out bad practices (tons of unused javascript libraries). SPA frameworks are pretty damned good and they really can and ought to be used wherever you feel the need because some SPA frameworks are very quick to get started with and can be customized to significantly reduce bloat.
TBH most of the cons stated in this article are just because of bad programming, not because it's a SPA

> broken “back” button (sometimes it works properly, but in general people don’t trust it)

If your UX is good, the user will notice data is refreshed when going back. All current top tier SPA Frameworks have support for correct HTML5 routing.

> broken “open in a new tab” behaviour – people like to handle links in onClick handler, and browser can’t recognize it as a link (even if the majority of the links are valid, sooner or later you’ll encounter a non-link “link”)

Again, most up-to-date frameworks have a fallback by adding a normal href so you can still CTRL-Click it.

> sometimes broken “refresh” button – after refreshing you end up in a different UI (usually slightly, but still different)

I don't see a real disadvantage here, since you can simply store your state by manipulating the URL or even localstorage. So you even have the possibility to not store your state...But again, application design, not SPA

I do agree with TTI (at least on the first load) and bad performance on low end devices.

No. Because it is an SPA, it means there is more work to restore the default behavior of the back button. That's the way he should have articulated his point.

You also mention HTML5 routing.. Ok now you have to configure your web server to properly parse the URL and understand what it's conveying.

And all of that work is already done for you in all modern major SPA frameworks.
Server side too?

Client side routing? Have you seen the huge chapter dedicated to routing for angular? You make it sound like it's no work

> Server side too?

Yes

> Client side routing? Have you seen the huge chapter dedicated to routing for angular? You make it sound like it's no work

Haven't seen angular's, they were late to the SSR party.

Server side is as simple as taking /app/* and having it hit your SPA
> TBH most of the cons stated in this article are just because of bad programming, not because it's a SPA

The worst programming is the result of choosing the wrong tools for the job. There is a class of jobs for which an SPA is entirely unnecessary.

Great to see the article posted on a "classic" (static) website built w/ jekyll. Find more open source (ready-to-fork) themes @ https://drjekyllthemes.github.io Build your own "classic" websites / blogs :-).
As an avid developer of SPAs (currently working on one for my own blog frontend) I'd say a lot if this stems from people being convinced SPAs 1) provide a faster development cycle, 2) they believe that they've offloaded all need for optimization on the framework they use and 3) "serious" development teams build SPAs.

Anecdotally I find SPAs, while I'm more comfortable developing them, will take longer to build. You need to pay more attention to the quirks the author mentions and you need to spend more time explicitly optimizing your code. I like this paradigm because if there is inconsistent logic, poor performance, or other issues, it's my fault and I have the opportunity to fix it.

As a counter example to the ones mentioned in the above article, around 2 years ago I build a drum machine webapp entirely in JavaScript/React (https://io808.com). This has ~17 JS library dependencies and ~6000 lines of source code but the gzipped bundle size comes out to ~97 KB.

Just because you're building an SPA doesn't mean you need to spend less time optimizing your code, in fact it likely means the opposite.

I’ve used React in the past and I believe what you’re mentioning is very React specific.

Angular has lazy and eager loading, which reduces bundle sizes. It also doesn’t require so many frameworks to manage manually. They are still there, but they are sort of imported automatically by angular cli so it doesn’t take a lot of mental overhead.

Some issues I had, though, were with bugs in newer versions. Some of those issues stopped development outright.

Another issue I have on one team is the fallacious notion that the front end programmer will take over the front end so no one else will need to think about it. Business specific logic seems to be out of reach for my particular developers, which prolongs the development cycle.

The benefit of state management and inter component communication have to be balanced the the practicality of who is doing the work and if those people can take ownership of all associated areas touched by the SPA.

is there a way for React to do eager loading? i asked around on twitter but got told "thats not React's job".
Loading of modules can be managed by Webpack's chunk configuration. Each import declaration can be turned into a promise that executes your code when all dependencies are fetched.
I think the react dev team is currently working on an official async loading pattern for a future update. But currently webpack, rollup, etc. offer dynamic import, code-splitting, tree-shaking
Not sure if that's what you mean, but when Andrew Clark keeps mentioning the "async" word, he means async rendering, not async loading.
What is an unsolved async loading problem in React you are experiencing?
I don't have any issues with async loading. I'm just saying that I believe what you are referring to when you say the React team is working on an official async pattern is not actually async loading, but async rendering.

At least every time one of their members said the word async in the last couple of weeks/months, it's what they referred to, and it's a completely different (and unrelated) thing. I can't read your mind though, so I'm just guessing.

Not sure many people think SPAs provide a faster development cycle, individual pages are always going to be more simple.

You'll get code reuse but that's trivial to get working elsewhere, you just save on redownloading shared code.

Missing out of this conversation is the operational side. Moving beyond localhost, analytics, seo, content mgmt that create a whole different set of challenges vs non-spa.

Likes others have mentioned, it's about the UX that you want to provide that dictates the SPA path.

I really like your dials/knobs on the drum machine
Tangential question: what is the best practice for handling authentication on a SPA? I have seen JWT being heavily criticized on HN and elsewhere. What is the alternative that still maintains the separation between front- and back-end?
Like anything else it depends. JWTs are still great. Just don’t treat it like a classical session and dump important information in it.

You could also use session like you always have if the SPA is being served by the same server.

JWT is at the heart of OpenID connect, I agree they’re still perfectly reasonable.

The big issue I have with JWT is they are hard to invalidate for security reasons, but if you lower the validity and refresh the token more often you can mitigate (not eliminate) the risk.

Tangential answer: It would vary based on sensitivity of your application. JWT is not a bad option if we do not have a requirement of absolute session termination and if implementation does not have any vulnerability. People also use cookie shared on the root domain(backend and front end can be served by different sub domain. Also you can use custom headers since cookie is just another type of header managed by browser itself. The additional work would be around managing the additional header on back end. People generally open doors for CSRF attack by separating front end and backend like this. Good thing is that there are simple solutions to mitigate that risk too.
Is anything ever?

Why is there such a strong tendency towards treating things as a this-is-it(-this-time-for-real) thing? This only confuses people and muddles up expectations.

Not the most compelling list of pros/cons that I have ever seen.

In terms of raw performance for content sites, I found hybrid implementations like Gatsby.js to beat most things. Most of the cons of SPAs can be significantly diminished with SSR, proper chunking, and a variety of other modern techniques -- it just gets complicated in a hurry.

For anyone reading this thread and thinking about server side rendering their single page app: do not go down that route unless you’re willing to also implement proper chunking! If you SSR your pages, but still need to load a giant bundle, you will get the worst of both worlds: a page that looks ready, but makes your users extremely frustrated because they can’t interact because your app isn’t booted yet.
What's chunking in this context?
Breaking down your JavaScript bundles into smaller files that contain the code necessary for the route you’re actually going to be viewing once the page is loaded. For other routes, you fetch the necessary code on-demand.

This lessens the CPU power and bandwidth needed to initially load the page.

This isnt a problem with SPAs per se, just a problem with the app's design.

You can split SPAs into multiple apps that communicate. The main app would be loaded on open and the rest of the source could be pulled in when needed.

React is not the cause of slow loads, your architecture is.

Can we start a movement to teach tech bloggers what "begging the question" is?
This might not be a popular opinion here, but yes, SPAs are indeed a silver bullet.

Or at least, no you shouldn't make a site that isn't SPA. With universal rendering, light frameworks like Preact/Inferno.js and things like microjs.com , you can make a site that loads faster, renders faster and navigates faster then a multi-page application. You can make SPAs behave like a regular site - with links that work and all.

It's simply that many developers/managers don't care for or know how to make fast websites with SPAs, but then again even Multi-page applications are usually bloated with dozens of marketing, analytics and third-party libraries which makes them just as slow.

I don't think reloading the entire page on every request is acceptable in 2018, even if it's a blog.

I thought gatsbyjs was a nice medium ground. You have the familiarity of a single-page app in terms of stack and yet have the quick loading times and back button, SEO all of that since it produces a static site. I thought it was genius but I'm biased because I like react.
Agreed. The old CERN website is pretty fast, but Gatsby actually loads subsequent pages much faster — hardly any discernible delay.
Funny you mention it, I just started looking into rewriting my portfolio website (http://sdegutis.com) from a custom node-based static site generator to use Gatsby.js, in order to get more practice with React.js. Really curious to hear what other HN regulars who've used Gatsby think of it...
I used it actually because I love react but needed to work with a great designer who already knew sass and I needed to include react components but also wanted to hook it up with a cms too. Check check check... keeps going and produces a static site. Wow. Even the designer could use this and modify things for simple components, not knowing react. I'm pretty happy so far.
One thing I'm noticing about SPAs is that they're often slower to load, but the slowness and loading animations gives me a higher perception of the quality of the application.

The same application loading and doing things instantly as server-side templates feels comparatively cheap and un-modern.

What is wrong with me?

Just a guess: You were alive when progress marched on before your eyes. Animations are "new" to you, and like many people you have some sort of implicit association somewhere in the back of your mind that "new == better"

Do you ever find some animations to be lower quality than others? E.g. a pop up with a progress bar being lower quality than a spinning wheel? That might be another sign.

Maybe to this day, Zombo.com is just an SPA that nobody every gave enough time to totally load. I mean after all, it was written in the late 90's and SPA technology wasn't that sophisticated back then.
I recently started blogging again, and I chose to go with a static site generator. It's fast, really fast. Loading a whole page with each click is so much faster than visiting most of the sites I visit each day.

I'll never get why we collectively decided that it's reasonable to grant every random website in the world execute permissions on our machines.

Over 90% of my web browsing is done with JavaScript turned off. When I hit an spa blog I sometimes read it, sometimes not. Clearly if the owner of the blog is so insensitive as to make it an spa, they don't care about the content and especially don't care about their readers. That's fine. There's plenty of other content on the web to read. I don't understand why it's normal to let strangers run code on my computer. Yes, the masses are ignorant of the consequences, but I think that's slowly going away as me generations grow up with the internet. Anyway, the upside is that over 90% of web pages I visit load under a second. Imo, people who make their blog, marketing site, etc. an spa blindly don't care about their content, presentation, or the reader. Why would the reader care about them?
I was thinking about this recently watching a major web app throw a bunch of errors and slowdownsall to do with its SPA features. If it was just a normal web app it would be so much faster and more usable. It seems crazy to me that we have faster and faster computers and internet connections, and yet we've added all this new latency to the software we use.

I find the list of pros somewhat unconvincing.

For a lot of applications, a reload is no hardship, and is faster than most SPA interactions I see.

For a lot of granualar actions, jquery, while not sexy, is not harder to maintain than a full SPA would be.

The alleged development efficiency of decoupling front from back really needs context and argument.

As I see things, there are a lot of web projects where a normal app with a little progressive enhancement is a good solution.

Hold up, most these problems are directly related to the problems of using React+redux (JSX) and likely some complicated backend stuff.

We use Vue + Firebase and even have SSR working w no complaints. (So it's actually more than just a SPA)