Hacker News new | past | comments | ask | show | jobs | submit login
SPAs: theory versus practice (nolanlawson.com)
99 points by todsacerdoti on June 27, 2022 | hide | past | favorite | 68 comments



I actually posted a piece today, comparing the performance of every website on madewithangular.com with every website from the next.js showcase:

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.


This article compares the CPU times of every site using Angular/React/Vue/jQuery known by the HTTP Archive and comes to a very different conclusion: https://timkadlec.com/remembers/2020-04-21-the-cost-of-javas...


It looks like the author has come to a fairly similar conclusion, albeit from measuring something completely different:

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


Great article.

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.


Yeah does every site need Gmail levels of complexity when simple HTML and a sprinkling of CSS will do the trick instead? There are people who disable JS for accessibility reasons and are locked out of reading certain text just because it requires JS. Then there’s the remarkable low effort of what’s put into the <noscript> tag. No description apart from the familiar: ‘This page requires Javascript’


Gmail doesn't even need gmail levels of complexity. The "basic HTML" version is already pretty good, and some very light extra javascript could easily cover what few gaps it has, no need for an SPA.


The biggest crime - and I blame Google for this - is making basic web-components, even a Hello World mandatorily need Javascript. There was no need for mixing up web components with JS, except it didn't fit Google's agenda.

Custom tags using HTML+CSS with no JS would have been utterly amazing for web fundamental development.


Genuine question from somewhat newbie in web components but afaik is JS required just for mounting a custom element, let alone its inside?



Ah, I missed the important _would_ in your line. 100% agree on you.


Why would I let the marketing team have any say in the site I'm working on?

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


I mean - if your website is selling a million widgets a year, the marketing team are going to pretty involved (especially if you want to keep selling a million widgets a year)... So getting them involved in the spec is probably pretty prudent.

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.


Right. We agree then, there arn't a lot of content sites that would benefit from being an SPA. it'd have to be a multimedia extravaganza really. And since most of the web is mundane content sites, SPAs should be rareish on the public facing internet

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.


Well yeah. But at no point did I infer that everything over http was the same as the projects I'm working on. I literally started the comment with: "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."

And you're right, we absolutely agree that SPAs aren't needed the majority of the time.


> Want to avoid re-rendering the whole page, when there’s only a small subset that actually needs to change? You can’t; it’s a “full page refresh.”

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.


Exactly right! I find the SPA vs. MPA debate to be tedious, if not downright misleading, because it's perfectly possible build a web app that starts out as a basic MPA and then with (hmm, what's that term I'm looking for…wait for it…oh yeah!) *progressive enhancement*, you make it more and more SPA-like by loading in HTML fragments and making incremental DOM updates, updating the URL whenever possible to mirror backend state, etc. Heck, just with Turbo Drive alone, you can eliminate the "full-page reload" problem of MPAs with essentially zero (custom) JavaScript and it works great with static sites, full SSR frameworks, you name it.

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.


This. Call it MPA Foundation, or something. With an MPA foundation there are plenty of opportunities to make easy improvements to performance and page experience, while still having all of the page features work without JavaScript.

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


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

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)


What's up with partial refresh that developers want it so much?

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.


Your point seems to be more of HTMX vs React rather than SPA vs MPA.

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?


Fantastic article and I totally agree with Nolan here:

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


In the best case scenario someday building an SPA will be closer to building a mobile or desktop app

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?


Making an application where you have full control over what's going on is never going to be simple.

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.


I actually find building SPAs much easier than building MPA from complexity and performance pov. I have done ASP before, then ASP.NET Webforms, then ASP.NET MVC, then angular, then react.

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.


The performance angle of SPAs has been proven wrong many times.

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.


> If SPAs had better perf than MPAs, I can assure you Amazon (the store) would be an SPA.

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.


I don't use Instagram so I can't compare. I don't use the Amazon mobile app either.

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?


Amazon app is actually a glorified webview.


Are you _amazon_? Nearly none of the companies have the scale of amazon, nor the needs of amazon. "It's proven many many times" is all in the eyes of the beholder, i'd say. Sure it might be slow if you are optimizing for 1ms latency, but that's not what 99% of the people do.

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.


I am really struggling to understand your pov. I can throw together a whole app in asp.net MVC in days that takes weeks with react. Adding that extra layer of complexity of an API and duping the models adds a ton of work on top of everything.

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.


Amazon is highly optimized for conversions on a single navigation. This is not representative of all web use cases. For ecommerce, I would agree with you. This is generally true of any site where a significant amount of the visits are load one page and then bounce to another site. SPA advantages don't help in your primary use case.

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.


This is my experience as well. The SPA works best when the application is doing a bunch of stuff on the client side. If it has to make a bunch of trips back to the server, it's going to be a headache to debug.

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.


Even if this were true, you are sacrificing your end user experience for having a better development experience.

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.


I'm curious: What problems do you have with the Cloudflare dashboard that seem to be SPA-related? I use it regularly, and the only problem I can think of encountering is that it never remembers my "desired location" when it redirects me to a login form—If I go to view the firewall graph (navigating from my browser URL bar with autocomplete based on history), it will send me to a login page and then dump me back onto the big "overview of all sites" page. But this is hardly a problem specific to SPA apps! Every multi-page app I've ever worked on had to implement some sort of "login_desired_location" cookie if they want to get this right, and very few of the apps I use ever get this right—regardless of page architecture.

(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!)


It’s slow - it’ll render in 1-2 on an M1 but then you get spinners or other progress bars for a while as various API calls return (each GraphQL call is like 5 seconds).

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.


My main issue with the CF dashboard is that it's spinner-hell. It's fast, but there are spinners and layout shifts everywhere.

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 quote you shared is utter non-sense. I have built SPAs running on devices so underpowered, you wouldn't believe. Single core, 512MB RAM, no GPU. And with a browser running on on top of all kinds of other crap.

Right tech for the job. Where "the job" could be anything.

Considering what modern browsers run on.


The context of that quote is mostly about dev complexity.

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.


Eh, but one could just as easily say "non-SPA" websites aren't all that great either, see? The real bloat is the 15 trackers and ad platforms, imho. I am not advocating for SPAs, btw. Personally, I mostly browse with JS disabled.

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.


The biggest downside to SPAs are that a lot of retail eCommerce companies seem to have built average SPAs. I've run into cryptic error messages when trying to do some kind of transaction ranging from mundane (buying toilet paper) to high stress or important (buying plane tickets for a work trip next week). Worse yet, seeing no error messages and going into the web browser's dev console to see the error message.

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.


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


Amazon is MPA, right ?


Disappointed this wasn't an article about bath houses


Same, the title's casing should be updated.


Same! I came here for an article about hot tubs.


I get that this is HN, so context is provided, but really the title should be capitalized correctly. 'SPAs' not 'Spas'. You do see the oddball story here, and I was wondering if this was going to be about bacterial profile of hot tubs.


I misread it as SPAC and then jacuzzi and finally realized what it was referring to once it loaded.

Which is sad, because the first two were more interesting to me.


Another issue: not everyone has JavaScript enabled, and it's good to back off to something useful without JavaScript where that is sensible.

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.


> not everyone has JavaScript enabled

What are the stats? I assume it's > 99% have JavaScript enabled. Any significant percentage could be down to corporate policies.


Stupid question, but given that most analytics are gathered via JS, I wonder if that might fall into the same sampling bias as "we called 100 random people and everyone has a phone!"


It's a good point. I'm not sure how it would be tracked. I just can't think of anyone I know that even might browse with JS off. It's on as a default setting and I think it is fair to say that most of the world don't know what JS is.


> I just can't think of anyone I know that even might browse with JS off.

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)


Most people leave JS on, but several browsers (e.g., Tor browser) and browser extensions make it easy to turn ir off (e.g. for improved security). Many tools, e.g. Lynx, curl, wget, do not implement JavaScript.


With some magic image inside noscript tag.


In the last 20 years doing web development, I haven't ever had one single colleague, friend or customer complaining of any site not working because they had disabled JavaScript. Literally didn't heard about anyone around me with this problem not even a single time.

The only place I randomly see mentions this problem is in HN.

That has to count for something.


Some of it, too, is that if it were more practical, more people would disable it.


Even if building MPAS with js sprinkles, nobody is going to put the effort to build and test a non-js versions for the 0.01% of weirdos turning off JavaScript in 2022. Just don't use my service


I do. It's easy to test. If it's a simple CRUD application, just test to ensure that simple read, edit, delete are supported, typically using REST. Done.

In fact, it's much easier to test than seriously testing a system with client-side JavaScript.


A single page app is nothing but JavaScript that can render pages without a full refresh. That's it. People seem to have this idea that a single page app is something else, in particular an app with little to no server generated pages, but if you even just have Turbolinks then you now have a SPA with some HTML coming from the server.


People seem to have this idea that a single page app is something else, in particular an app with little to no server generated pages

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.


Some developers prefer generating HTML in server side logic using server side templating tech. (Rails. C#/Razor) So when that is the case, the only benefit of SPA is avoiding a page refresh.


I find when most people refer to SPAs they actually mean PWAs


This can be generalized to any opinionated technology: making a platform/language/whatever more opinionated lifts the average case, and lowers the ceiling. This is one of many pervasive and recurring trade-offs in our industry. The web is an opinionated platform, that has this giant escape-hatch called JavaScript. If you choose to go off-roading, you have more power and also more responsibility.


> "right down to esoteric topics like memory leaks. (Do you have a team like that?)"

Y..You... Your team thinks memory leaks are an esoteric topic?


In frontend web development absolutely.


As is most computer science lol


Back then, there was no good tooling for the topic.


> and multi-thread that JavaScript

yeah ...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: