Why does everyone suddenly hate Single Page Apps?
begin.com
begin.com
Depending on who you talk to or what online forums you frequent, you may have had an impression that the first group was far smaller (or larger) than the last group. Due to changes in the media you consume, or changes to the culture of various online forums, it may seem to you like the first group is now larger (or smaller!) than the second instead.
On the margin I suppose a few people who liked SPAs due to the novelty may have got bored with them, but most people, I think, have had pretty static views about SPAs, because the pros and cons are pretty obvious.
Yeah, okay, some prominent engineer tweeted something bad about SPAs last month and it went semi-viral, but prominent engineers have been tweeting and writing bad things about SPAs for the entire existence of SPAs. And more than a few of those have gone pretty viral.
Better question might be "How come I saw this tweet on my feed, but didn't notice all the earlier ones?", but I don't think that's super interesting.
Google Maps was a justified SPA. But when I am looking at a normalish looking web page and can’t open hyperlinks in new tabs cuz they aren’t actually hyperlinks, or the back button doesn’t back, you’ve broken fundamental navigation. Back and forth shouldn’t refresh lists and reset scroll.
Too often SPAs completely reinvent browser navigation within themselves. And I know the argument is that it is indistinguishable, but from a performance standpoint, you’re now running a second copy of browser functions in ram/cpu for every tab open.
Something similar happened about a decade ago when everyone started loving SPAs.
SPAs didn’t become popular because of cell phones. In fact, outside of Facebook for a short period of time, there has been a strong consensus over the entire “everything must be a SPA” period that mobile apps should be native. Facebook, once it realized its mistake, tried to fit its massive “build once run anywhere” peg into a tiny “native for mobile, HTML5 for the web” hole through React Native, not SPAs.
SPAs have their place. Although I’m not a huge fan (though less of a hater now, thanks to the fact that at least the JS world has largely agreed that typing is good), I have a highly successful SPA that’s been used with almost no maintenance besides basic security upgrades for nearly 7 years now.
The reason is that we used a proper framework that fully supports building a SPA, EmberJS, but it could have been anything other than trying to cobble together a variety of react-* libraries thst only barely work together, and that our application actually was a heavily interactive user driven application with most of the stuff happening on the same page. There are only a few minor other pages (such as settings), so the application itself is largely a single page application, which is why a SPA fits it so well.
Instead, it insisted on being a thin UI layer forcing others to fill the gaps, which have led to all sorts of startups/open source projects popping up trying to convince others that theirs is the one true way.
So instead of being a sober discussion around the pros and cons of using certain technologies in certain scenarios, it’s being recast to resemble the fashion industry where everyone is insisting that their trend is the next big thing.
If they were still easily accessible, you could go back and read identical drama play out on 50 year old usenet newsgroups and mailing lists. Our industry is built on the genius of many clever tinkers who could get any tool to meet any task, and plenty enough stubborn contrarians and manic hype-builders ready to argue to their death (or until the next fashion comes through) that the one true light has finally been glimpsed.
Meanwhile, countless quiet and productive teams privately figured out how to use a tool well and just stuck with it for as long as it still made sense, not letting themselves getting so wrapped up in the public hullabaloo -- just like you did with your EmberJS project.
The fashion debates reflect that a lot of work is actually art, while those many quiet, healthy projects reflect the engineering processes that see us get paid better than most other artists.
I’d like to think that as a field we’ve learned something about measuring claims or not picking your architecture based on what someone in a different business with different users is doing, but experience otherwise.
A web application or a website, by its very nature, is a series of small requests. When someone sends all requests in one big lump of a page, they have just defeated this very important architecture. Not to talk about the fact that they break searching on pages and a whole lot of other things.
We spent the last decade trying to fix the whole mess that client-side "rendering" created in the web, we'll probably spent the next decade trying (and failing) to standardize things such as web components, declarative shadow DOM, among other things. That's because we as developers keep insisting in complexity: hydration, SPAs, bundlers (and in consequence bundle bundlers such as Vite). The only true solution is to bet in simplicity, but that's not sexy, and sex sells.
In conclusion: The React revolution and it's consequences have been a disaster for the human race.
There is nothing inherent in SPAs that make load time slower. If your REST API takes 5 seconds to serve up JSON, what's to say your SSR rendered page won't also take 5 seconds?
> Are you saying search engine crawlers haven't figured out how to deal with that?
Except for Google which has spent a tremendous amount of effort on that, yes I am. > There is nothing inherent in SPAs that make load time slower.
I never said they are. The difference is only for crawlers which now have to run JavaScript whereas before they could just retrieve the document and index it as it was served to it instead of trying to determine when the SPA has done the full loading of the page.https://stackoverflow.com/questions/36702789/google-crawler-...
Till today the Google Crawler is the only one that gets even near good search results of SPAs. That's because they have to run a full browser to load every page to parse it. Every. Single. Page. That's why it is hard to do correctly. Read a bit about their current approach here:
https://developers.google.com/search/docs/crawling-indexing/...
Specially:
> Keep in mind that server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript.
Recently in 2019 Bing Bot just gave up and is using the same approach a Google:https://blogs.bing.com/webmaster/october-2019/The-new-evergr...
So nowadays having a SPA isn't as bad for SEO as it used to be, but again, and I'll keep nailing on this, that is only because we spent the entire last decade throwing millions of dollars and hundreds of hours of engineer time to make SPAs a viable option.
Next basically is React and the React team implicitly admits this.
We agree though, it's just a naming thing really. I make the distinction like this because traditionally a SPA can simply be served by a CDN since it's simply a single file, meanwhile all of these frameworks either require a server to render pages on request or prerender all the applicable pages and leave a few of them to totally client-side "render".
Also note how Vercel (at the time called Zeit, mostly known for Now) called Next.JS back in 2018 when they originally released it:
https://web.archive.org/web/20180628030830/https://nextjs.or...
> Next.js is a lightweight framework for static and server‑rendered applications.This whole take is just bizarre. Literally none of this matters to users except to the extent that it affects performance. While I would agree that many/most SPAs are implemented extremely poorly and inefficiently for reasons relating to what you're talking about it, and that that poorness spans both technical faults and UX problems, it's a very myopic view to complain that the foremost function of the web should be to rigidly adhere to a particular set of architectural patterns that are in flux and often outdated by modern standards.
Users prefer the hypertext model to opaque blobs.
Being able to bookmark deep links matters. I've worked places where users complained they couldn't bookmark their work because everything is just "the page".
Not defending SPAs, just pointing out that they are not to blame for this.
Yeah, just render my browser's back button dysfunctional, fam. Doesn't matter to me at all. Take all my control away and lock me into your walled garden of totally custom, approved-only interactions.
I have a hard time seeing this as how most SPAs work.
I see this as how most SSR systems work. Which does seem broken & bad. A user has no potential to understand this world. It's just a mainframe generating some pre-rendered experience that has no real data inside of it.
So actually, no. I think SPAs have moral value. The alternatives that have upstarted recently seem bankrupt, with no legs to stand on. I don't understand where this post comes from. There's an extremely hostile negative high-bullshit pissy attitude here, that isn't backed up by a single thing I can recognize:
> There is no sudden about it, SPA's are yet another one of the so-called "modern web" cancers of the Internet.
Most SPAs seem to be the last defender of doing what you asked for?
I'm over it. Even the simplest SPAs end up being way more effort than they are worth IMO. I'd write thin API layers and it seemed great.
Recently though. I moved to all backend with some jQuery. I render all the views on the backend and if they need to be swapped out I make a simple ajax call to pull the rerendered days and swap the div. It's like 2 lines of code for me.
Everything is so much faster, primarily because JS has so many gotchas. And so many times where you wonder "wait why isn't the data right here? Shouldn't this have blown up".
There is no appreciable difference to the user here but I can work in a backend lang and sparingly use JS and it's a pleasure.
Sounds like one of those bad SPA in the making. You know, without browser navigation, without an url that can be revisited.
It was early in the 2010s that I saw all the web design shops who made Ruby on Rails sites in my small town suddenly start building all their apps in Angular and struggling.
I'd ask them why they were doing this and it wasn't masochism, rather they believed that small town web clients demanded SPAs and that they couldn't sell user-friendly RoR apps that were affordable to develop.
Web apps/spa/pwa can be a great value choice if you need to hit a lot of platforms on a budget.
Angular definitely started out as kind of a dog. Some modern frameworks I'd put up there with ruby, maybe better. Don't chase the hype. Lots of great tooling out there. Prove something out before you run with it. It's not THAT hard.
And that was already a while after Outlook Web access, and even later than people using hidden iframes to simulate XHR before XHR existed. They might not have been common, but they're old by now.
The solution to bad url routing in SPAs is distributing our work across a madcap wild ass front-end/back-end split with ill defined borders & no protocols? What's happening now is 500% more complicated.
But the magic is well packaged & available by default.
The SSR world has frameworks: but as another commenter pointed out, React stopped at being merely a library. And so it's been anarchy, deciding how to SPA, with many folks not realizing how many needs/libraries they really needed to have.
I'm hugely in favor of SPAs, but there's been a lack of well-integrated sensible approaches. The attempt to identify & only solve a narrow window of concerns has hurt our ability to imagine what apps are, left huge voids all over.
The hate for single page apps is about bad ones. Which are unfortunate common
What happens if you press shift? or cmd? and in which browsers / OSes? What if you use enter to open links, will it have a tabstop? What about accessibility. You're in essence re-creating the many parts of the webbrowser.
> The hate for single page apps is about bad ones. Which are unfortunate common
That's the same reason people hate php and c++
You can make great things with both..
Things like React Router make it trivial to create real links that additionally can change the page without a page reload if they are clicked. But you can still middle click to open in new page, still hover to see link, still navigate history normally, etc.
Sure you can make this work, but people don’t put in the extra hours of education, research, implementation, and testing
Imo the main issue with spas is they can be very fragile and don’t handle errors because they were built lazy. And since it’s all async, the spinners keep spinning forever despite the request failing already.
I think that’s the key point: the more browser functionality you take over, the more of a resource commitment you’re making to support that extra code. If you’re Google or Spotify, you can easily afford that and in the latter case you have a strong argument for necessity because there’s no way to keep the music playing across page-loads.
The key part is making sure that you’re taking on an appropriate level of work for your team and site. A local restaurant website should probably prioritize loading quickly since most people are looking for fast answers and the owner doesn’t want to pay to maintain a heavy tool chain which requires frequent maintenance.
- SPAs make sense for "applications". Google docs, Gmail, Trello, Slack, web-based music video creators, etc. Things that need high levels of interactivity. - SPAs don't make sense for "websites". Blogs, forums, search engines, news sites, etc.
Of course, many things exist somewhere on the continuum between "website" and "application", and then the tradeoffs get messier.
Gmail arguably doesn't need a high level of interactivity - that's why they also have the basic HTML version.
At $dayjob I regularly see "SPAs + microservices" getting deployed for static content that could have been literally just HTML, CSS, and JPG files.
I've seen a design recently for a trivial app that had two Kubernetes clusters in the architecture diagram. Two!
Not to mention that virtually all SPAs are infected by Node and NPM, directly or indirectly. JavaScript package management seemed "so easy" at first, and has slowly but inevitably morphed in a nightmare.
Minutes of CPU time was insufficient to disentangle the dependency graph of one particular Angular app in the effort to upgrade its packages. If hundreds of billions of machine instructions aren't up to the task, a squishy meat brain definitely isn't either.
Maybe SPAs are a great idea if they are your only product and are truly used to develop web applications that are constantly maintained. For corporate web sites they're idiotic beyond belief.
2) They're slow to start
3) They usually lack a good UX (deeplinks, hijacking links, etc)
In the earlier iterations, SPAs broke navigation, broke SEO, had no decent state management solution, and required a good understanding of reflow/repaint to avoid performance issues.
The ergonomics of SPA frameworks has improved drastically and metaframeworks like Next.js have mostly fixed those issues. But the myriad of options and paradigms might be exhausting for some devs.
Some experienced devs might be nostalgic for the document-centric PHP days. I imagine that many newer devs have only recently been exposed to the pleasure of building a simple MPA website, as they were initially thrust straight into React.
For example, I recently chose to use Hugo for my blog. Just wanted something dead simple to build a static website without all the bells and whistles of a SPA.
I hate SPAs when they're used for crippled website functionality and slower load times than a normal server round trip.
Now though, there's a couple of entities who benefit a lot ($$$) by telling people "Actually, this SPA thing sucks, look at OUR solution that will solve all your problems!". And they're VERY vocal about it (much more vocal than people who actually dislike SPAs).
A lot of trend setting in the tech industry is just from people ruffling feather or sowing confusion on purpose to then sell a solution. Right now we have a FEW of those, a bunch of people making money out of training you to solve the problem you didn't know you had, as well as a couple of Youtube "influencers" making money from the confusion.
Then he released SvelteKit which has the best of both worlds: https://kit.svelte.dev/
Server rendered or static sites make sense in some specific use cases (e.g docs, blogs), but even for those classic use cases they’re not ideal (e.g full page reloads every time).
On the other hand, SPAs make sense in some specific use cases (e.g Gmail) but even for those classic use cases they’re not ideal (e.g first render takes time).
I think we always need both server and client rendering, regardless of the use case, and the question we need to ask is how can we achieve this in an ergonomic way.
There’s some progress being made there (e.g Next.js) but I feel like it’s not quite there yet.
This is how silly this weekly SPA vs SSR debate is.
The money isn't there for offline ability on most websites. So... I can appreciate it from a distance.
Angularjs burned me so hard that i didn't even bother to look at react.
There are a lot of SPAs that shouldn’t be SPAs, but that doensn’t mean all SPAs are bad. This isn’t your grandpa’s web browser anymore. We’ve moved on from the web being all about hyperlinked documents. The browser is also an app runtime, just like your smart phone.
If server-side rendering was the only good way to build web apps, then it stands to reason thay it’s the only good way to build phone apps with equivalent functionality. Maybe phone apps should also start re-rendering the entire UI on the server every time the user taps something.
To build, you just build.
The latter makes less noise online.
- The SEO argument is long dead.
- Client devices are sufficiently performant for anything you throw at it. Yes, even the $100 Chinese Android smartphones that taxi drivers in India use.
- The last argument I've heard is "I don't want to expose a JSON API to the world", but that's false security because scraping a web page is not difficult.
Spinners stink.
Possibly true of the devices themselves (although dubious generally), but definitely not true of wireless networks. If you can deliver a rendered page in 10 KB versus a 1 KB doc and 120 KB of framework to render that same page, you win. That’s true regardless of whether it’s a 3G connection or 5G.
SPAs can hold a small advantage in the aggregate, so if you expect your users to be bouncing around routes quite often within a session, you might amortize the cost of the view framework and bundles, but that’s probably not the typical case on mobile, particularly in developing regions.
The whole point of SPAs is to run code on the client instead of servers. That tells us that the load time will favor SSR for any site where the code and/or supporting data is much larger than the displayed result. This means that the question of what’s better depends on how much data you’re talking about and whether you do enough dynamic behavior to make up for the unavoidably slower initial load time, and weather doing that dynsmic work locally is a net win relative to doing fewer requests over a higher latency / lower bandwidth network. This is different for every application so there isn’t a global optimum. Hybrid approaches (progressive enhancement, hydration) are also popular for blending the two, as are approaches like CDN edge execution, which again suggests different sweet spots for different types of applications.
The correct answer is to measure and adjust. I have seen exactly zero SPAs which delivered the authors’ original expectations for performance so I’d always rely on data.
This can also be repeated for reliability: SPAs can be great for reducing server load if you can run a lot of work on the client, but that comes at the cost of giving up control of more of the runtime environment and complicating monitoring and support. The right balance is going to depend on what you’re doing, who your users are, and where you’re running servers.
The other big factor to consider is development time. Writing an SPA requires shipping a lot more code to the client and taking on more responsibility to duplicate what browsers have built-in - for example, they usually have significant accessibility challenges which are easy to miss until late in the cycle. That extra code necessitates more work on things like packaging and since you’re running it on other people’s computers deployment is more complicated. Again, different teams will have different sweet spots based on their staffing, needs, and chosen tools.
But the runtime behavior will near-certainly far-prefer a thicker client model, where more is retained & locally available.
This was obvious & clear in the aughts, as web-apps emerged from purely server-side systems. Having a client that could re-render based on dynamic data was vastly better than trying to find portals of HTML to re-render & send.
It seems still likely & obviously true now. But folks sure AF love load time metrics!
> Having a client that could re-render based on dynamic data was vastly better than trying to find portals of HTML to re-render & send.
This can be true but again measurements will show it isn’t true far more than claimed in the SPA marketing materials. This is due to the reasons I mentioned in my original comment: if your SPA has to make a number of network calls to update the view with a modest amount of visible data, it’s probably going to lose compared to the same code running on a faster processor in a data center with a network path to the data which has greater bandwidth and 1-2 orders of magnitude lower latency.
The break-even point is going to depend on the type of application you have, how much data you need to touch, how well that can be cached locally or on a CDN, and where you run servers and their performance characteristics, and the usage patterns of your users.
This is why the hybrid approaches end up being most commonly successful: if you’re dogmatic about using one approach exclusively you’ll miss out on the optimizations which make sense for your users by trying to follow an approach designed for someone else in a different business.
There's problems, but the amplification problem is uber for real, and most of the complaints just don't frigging matter; this is 98% a Bullshit Asymmetry problem: it takes vastly more energy to care about & refute troll-ish petty behavior than it takes to generate it. Positive behavior rarely gets amplified. There's an outsized representation for anger/negativity, as there almost always is, everywhere, forever.
Personally I think it's absurd to favor servers. AKA mainframes. Thick client web systems have a fundamental embrace of user-agency, in a way that thin-client systems are utterly unable to negotiate. It's cheap and easy to take digs on how bad things have been, and 100%, there's been a pretty poor developmental track record & much could & should be better in the client side universe. But it's still 100% better a RFC 8890 paradigm - The Internet Is For Users - than literally all the rest of computing, which has nothing for users & offers them diddly squat in terms of agency.
Alex's critique / pouring gas on the fire is wrong for a simple reason: we've been asleep at the wheel & embraced little change. URL routing, incremental loading, offline capability, & a host of interesting sprawling new web capabilities that could improve everything are still drastically unadopted. We have a lot of libraries for orthogonal concerns, but there have been essentially zero successful efforts in the last decade to define a system even as comprehensively cross-cutting as literally the first successful JavaScript framework was, Backbone. We have reduced scope since, and left orgs to cobble together orthogonal libraries, which has strengths, but makes it harder to adopt & leverage the high minded better potentials of what could happen. The web just hasn't evolved or advanced significantly, in spite of some churning iteration for how we all React.
SPAs are wonderful, but we've crashed against the limits of what we are willing to explore, and there's been a lack of way forward projected, and the upsurge in anti-SPA SSR is basically just an off-gassing, a pent up pressure to do anything other than what we've been up to, and while it has some virtue, I still ascribe most of it's interest to the fact that client-side systems have been at a standstill & real coherence & sensible integrative holistic imagining of how we might better do SPA's has been obviously absent for a while now.
GraphQL was some attempt to respin the front-end world but I think by now we know it's not really actually much different or better, but there's ideas captured there, where front-ends are not as hand-craft artisinally-made that we still are far from, and there's countless capabilities we should be tapping - like good Service Worker patterns, much more webworker and distributed computing ideas - that have made essentially no progress. At some point we need to upgrade & enhance what we expect of SPAs, but while the tooling has changed somewhat (React moving from classes, to HoC, to hooks, Redux to whatever), there's been little actual embrasure of real change, real web capabilities, that have been all about.
SPAs are still one of the greatest best option out there, even though their means-of-production are essentially unchanged for a decade & the hipsters are desperately hungry for cooler/bettter. Even though we've hit this kind of so so local maxima, there's just nothing anywhere as effective, and the whole SSR pitch may fit some roles, but for like 98% of systems, a SPA has a ton of advantages in being a more unified isolated independent thick client that just networks back to a bunch of dumb resources, which is a better/simpler & less overhead model - albeit one with some more loading cost - than the radically weirder & more complex models of splicing apart the baby & having part of the work happen one place & part of the work happen elsewhere. And none of that is good for the user anyways. I look forward to a new novel exciting future, but this is not the RFC 8890 way forwards. SPAs are kind of stuck, but still the best version of the web we have.