SPAs: theory versus practice
nolanlawson.com
nolanlawson.com
https://alexkrupp.typepad.com/sensemaking/2022/06/angular-wi...
If you look at the distribution of PageSpeed Insights performance scores, it's very clear that choice of framework is not what causes bad performance. The data shows that Angular might be a little better than Next.js for getting top scores, but for the vast majority of sites, the reasons for bad performance have nothing to do with framework.
Put another way, the average Next.js site has a performance score of ~35, which is terrible. If you were to rewrite your site in Svelte, then maybe it would go to 36, which is still terrible. Unless you are already spending the money to be in the top 1% of all websites in terms of performance, then you might as well just pick a tech stack at random -- at least as far as performance is concerned, obviously there are other factors at play.
To make this even more concrete, let's say it would take 18 months to rewrite your front end in Svelte -- so ~3,000 hours to get an expected PageSpeed Insights improvement of 1 point. Alternatively, let's say it takes 5 hours to replace Moment.js with Day.js, which has an expected improvement of 5 points. That means replacing Moment.js with Day.js would be, on an hour-per-hour basis, 3,000x more cost effective than switching frameworks. And yet nearly every time I talk with a startup that is considering doing something about their slow SPA, it's usually just spending millions of dollars to rewrite it in some trendier framework.
"It’s worth noting that because sites with React or Angular spend more time on the CPU than others, that isn’t necessarily the same as saying React is more expensive on the CPU than Vue.js. In fact, it says very little about the performance of the core frameworks in play and much more about the approach to development these frameworks may encourage (whether intentionally or not) through documentation, ecosystem, and general coding practices."
CPU usage is vaguely interesting, although I assume the vast majority of people care more about their page load speed.
I'd also note that relying on technology detection from some third party is potentially going to be very misleading, unless that data is actually regularly updated. Sites change their technologies all the time, so even a significant percentage of the sites from the Next.js Showcase and MadeWithAngular.com aren't actually made with those technologies. Unless you take the time to either go through each site by hand, or else pull out the code from the Chrome extension for each framework to detect its presence in the way that the authors of that framework endorse, then you could easily have ~30% of the sites for each technology no longer actually using that technology.
In the 'real world' of my own little bubble, The average SPA is worse than the average MPA seems to come up pretty regularly, particularly in the ecom world.
I'm seeing more new sites being built as single page apps without any real need for them to be. Having been agency side in the past, it feels like either the businesses needing a new website are being sold some slick pitch about how SPAs are the future, or the devs have decided to reinvent the wheel because making MPAs is boring. Both are usually to the detriment of the end product.
When the new SPA site materialises there are SO many problems. Each one takes monumental effort to fix, because of stupid intricacies. External services stop working with it. Remember that thing the marketing team had been using for the last year? That no longer works; cue 3 months of reporting gaps. And that other thing you had in your tag manager? That now loads with every refresh (or not for any subsequent page!), and the JavaScript breaks after the first load. The data layer? See ya! SEO? See ya! Those Adwords gclids? "Oh we stripped those..." Etc. Etc. Etc.
I think a lot of the problem comes from developers not being in the weeds with the end product. 25 years of 'normal' sites and even the bits you don't know personally work pretty well. Stuff is solved. If you're the dev tasked with creating a new ecom site, if you've never had to put heatmaps in GTM, or enhanced ecommerce in the data layer for a checkout plugin - or whatever else - how do you know to build it in your SPA? And it's never going to be specced, because most end users just expect stuff 'works'.
I've used some brilliant SPAs. But jeez - do it well or don't do it at all. And 'well' shouldn't be judged by the developer.
Custom tags using HTML+CSS with no JS would have been utterly amazing for web fundamental development.
https://lea.verou.me/2020/09/the-failed-promise-of-web-compo...
It would be completely inappropriate.
If any of the sites pages appeared in any search engine I'd probably be fired, possibly be talking with lawyers....
-------
My point here is that not all sites are the same. SPAs don't work for content sites like blogs or a restaurants home page, or whatever. But for internal line of business stuff, they can work well.
That's not to say a shitty site isn't a shitty site. It's not ok for any app to take minutes to load
And you're right. SPAs don't work for everything, which is exactly the point I was making. I keep seeing websites that don't need to be SPAs and have been built badly. But for the right project they can be great.
My point was that a lot of people seem to think everything sending anything over http is the same as the project they're working on. The demographics for every site being the same. the needs and requirements being identical.
And you're right, we absolutely agree that SPAs aren't needed the majority of the time.
This is where we a missing the middle ground in the debate.
I do not consider a server rendered page that then uses HTMX (or "just" jQuery) to do partial refreshes or given areas of interactivity to be a SPA.
So yes I can have my MPA and I can have partial content refresh and that does not require going all in on SPA frameworks.
With SPA frameworks you can deliver pages that can be accessed by the user (rather than just a single entry point). The difference becomes how the developer decides to build the application. Do they load all of the apps data on the first page load or do they retrieve it as the user browses around?
Not because there are tons of users running around with JS turned off, but because every page load is running without JS until the JS finishes executing successfully ( as noted by many others ).
Usually the only gain is that you don't have to reload and re-parse all the javascript that is there for doing partial refreshes.
We desperately need better terminology around this stuff and the willingness to engage in nuance and see these it as a broad spectrum of various approaches you can mix 'n' match—sometimes all in the same project! Saying "oh this app's MPA, oh that app's SPA" will totally lead n00bs astray who aren't familiar with the production-level nuances involved.
Why not? HTMX is itself a framework right? The distinction between SPA and MPA that the article gives (and that I agree with) is that MPA's delegate routing and page transitions to the browser. This naturally leads to less control (which makes the best case MPA worse than SPA), but also less complexity (which makes the average case MPA better than SPA)
> I remain skeptical that we’ll get there, and even the best SPA would still have problems (complexity, performance on slow clients, etc.), but I can’t fault people for trying.
In the best case scenario someday building an SPA will be closer to building a mobile or desktop app. But even with batteries included (native widgets etc) those types of projects are inherently more complex than building a series of self contained pages.
Of course a great SPA is always going to be better than a great MPA, but the effort to get there is huge. I interact daily with SPAs made by corps with big budgets and they aren't able to get it right either. Some examples: the Cloudflare dashboard, the Google Cloud console, etc.
Just yesterday I was using the HBO Max web app and it was such a disgusting experience. It loaded 2MB of JavaScript for a simple password recovery form. And once logged in it was spinner after spinner after spinner. In some cases even throwing you out to others SPAs when navigating.
(The Google Cloud console is a complete nightmare, although I would argue that that's more for UX reasons then for SPA-specific ones—it seems honestly like the Google Cloud console is exactly as confusingly stateful and difficult to navigate as every PHP-based cpanel dashboard from the 90s: a hard bar to reach with any type of page architecture!)
Regarding the GC console, it has many UX issues, but regarding the SPA architecture my main complaint is that it's extremely slow and bloated. Every interaction takes seconds. Opening something on a new tab takes seconds. And there are spinners everywhere. I have to admit they recently pushed a new version that downloads less JS, but it's still pretty tedious to use.
The report graphs are similar: in theory that could be faster but in practice they’re not more responsive than late-90s PHP scripts were and the main advantage interactivity-wise is that you can update multiple filters in the time it takes the results to load.
This is generally okay, but I would use it as exhibit A for the argument that you aren’t going to see a performance win simply from using an SPA or GraphQL. You might find this approach lets you get further if you put serious effort into it but that’s not cheap or a given.
I find react the easiest, and cleanest way to do the SPA stuff, and it's much easier to get anything done with it than building MPAs.
If SPAs had better perf than MPAs, I can assure you Amazon (the store) would be an SPA. But SPAs are notoriously slow, specially if built with React. Amazon tested React and it was too slow for them so they kept using Java for SSR + jQuery. I think they removed jQuery recently, but keep using the same approach of SSR + sprinkled JS.
As for dev complexity, I'd be very surprised if that was the case. Are taking into account writing the backend code or only the frontend? What about client-side data caching? What about spinners? What about mismatched version of the app for users that don't close their tabs all day long? Etc. Etc.
Yes I know all problems with SPAs have solutions. But that's the point the article is making: you have to solve it.
What technology does the Instragram in-app shopping experience use?
Because whatever that is, it is 10x better than the Amazon app.
Amazon's websites, mobile and desktop, and app, are all horrible compared to the competition. Slow, hard to navigate, long load times, I wouldn't use Amazon as a point of reference for anything.
What I do know is that the Amazon mobile website, while ugly and outdated in many respects, runs ways better in my crap Android phone than probably 99% of SPAs.
I don't know, but it's probable the "Instragram in-app shopping experience" has better UX. Although that's not really what we're discussing here, are we?
Google also doesn't use react. The ads stack is written in C++, for fb it's hack + c++, neither of which are the right tools for majority of use cases.
But on top of that with C# and razor you've got strongly typed intellisense that just works which means rapidly building the templates which you just cannot achieve when making a spa.
In other use cases, which there are plenty, different sets of rules dominate. There are plenty of places where SPAs provide a much better user experience than MPA.
I find SPAs simpler to do than MPAs if it fits the use case.
To me, it's not a matter of performance one way or the other (server lag vs. overweight client). I'll deal with those issues when I come to them. What I care about is the ago-old problem of cohesion and coupling. I want the user-facing stuff in one place so that I can write and maintain it, closely cohering to itself and loosely coupled to the other parts of the system.
I'm a frontend dev and I work with React all day long. I still think MPAs and stuff like HotWire/Livewire/etc should be enough for like 90% of what we do. Being the last 10% offline first or Google Maps/ Figma level of interactivity apps.
Right tech for the job. Where "the job" could be anything.
Considering what modern browsers run on.
I've built small SPAs that perform great on low powered mobile devices, but that's not typically happens in practice. Even on desktop, most SPAs are super bloated and slow.
Complexity takes many forms. The last thing many* complex back ends need is serving a plethora of clients instead of data.
* See, I can do play that game, too. Coming up with "data" in support of my argument.
This is the worst case scenario for everyone.
Why does this industry have a pre-occupation with trying to increase complexity of the simplest things over time?
But at least when doing desktop/mobile dev you typically have a framework that leverages a lot of stuff for you. This framework is totally absent when doing SPA today.
A lot of companies over the past 15+ years flew too close to the sun that don't have the competency of Amazon or Google to build SPAs well.
Given how frequently the YouTube SPA screws up back button behavior, I don't know if Google deserves to be in the competent bucket.
And as far as I can tell amazon.com is still a MPA, which maybe says something given that this is a company known for doing research on now page load times affect their profits.
Which is sad, because the first two were more interesting to me.
Many security-minded folks think that "auto run arbitrary code from random websites" is more dangerous than the alternative. Indeed, this isanifestly true. Many sites should be able to provide a useful service without JavaScript. Sure, that's unreasonable for some sites (like Google docs), but for others it is perfectly reasonable.
What are the stats? I assume it's > 99% have JavaScript enabled. Any significant percentage could be down to corporate policies.
Hi new internet friend.
I have it whitelisted for some (perhaps many) sites. But even if it was on, things like google analytics are still blocked (at least I hope they are! Tracking is a never-ending battle)
The only place I randomly see mentions this problem is in HN.
That has to count for something.
In fact, it's much easier to test than seriously testing a system with client-side JavaScript.
what are you trying to say?
not generating pages on the server is the primary benefit for SPAs in my eyes. that's why i prefer to build SPAs even for trivial sites. because it drastically simplifies the backend. i don't have any site specific logic in my backend anymore. it's just a data storage. CRUD. i can reuse my backend for almost any site without modification.
sure, you can build SPAs while still generating html on the server, but for me that completely misses the point. the only html that is coming from my servers is user submitted static content.
Y..You... Your team thinks memory leaks are an esoteric topic?
yeah ...