It might be news to folks to learn that every single SPA framework has solved the problem entirely because it's really not an uncommon experience to have your browser history broken by a SPA. I believe that most frameworks implement the API correctly. I also believe a good number of developers use the framework incorrectly.
Bad websites are the results of bad developers, not the tool. You can have your history messed up by any kind of website.
But look, whatever. It’s Friday afternoon, I’m out of here. Have a good weekend.
Yep. It's bonkers to me that a page consisting mostly of text (say, a Twitter feed or a news article) takes even so much as a second (let alone multiple!) to load on any PC/tablet/smartphone manufactured within the last decade. That latency is squarely the fault of heavyweight SPA-enabling frameworks and their encouragement of replacing the browser's features with custom JS-driven versions.
On the other hand, having to navigate a needlessly-elongated history due to every little action producing a page load (and a new entry in my browser's history, meaning one more thing to click "Back" to skip over) is no less frustrating. Neither is wanting to reload a page only for the browser to throw up scary warnings about resending information simply because that page happened to result from some POST'd form submission.
Everything I've seen of HTMX makes it seem to be a nice middle-ground between full-MPA v. full-SPA: each "screen" is its own page (like an MPA), but said page is rich enough to avoid full-blown reloads (with all the history-mangling that entails) for every little action within that page (like an SPA). That it's able to gracefully downgrade back to an ordinary MPA should the backend support it and the client require it is icing on the cake.
I'm pretty averse to frontend development, especially when it involves anything beyond HTML and CSS, but HTMX makes it very tempting to shift that stance from absolute to conditional.
Even before that I was making Java applets to do things you couldn't do with HTML, like draw a finite element model and send it to a FORTRAN back end to see what it does under stress, or replace Apple's Quicktime VR plugin, or simulate the Ising model with the Monte Carlo methods.)
What happened around 2015 is that people gave up writing HTML forms and felt that they had to use React to make very simple things like newsletter signups so now you see many SPAs that don't need to be SPAs.
Today we have things like Figma that approach the complex UI you'd expect from a high-end desktop app, but in many ways our horizons have shrunk thanks to "phoneishness" and the idea that everything should be done with a very "simple" (in terms of what the user sees) mobile app that is actually very hard to develop -- who cares about how fast your build cycle is if the app store can hang up your releases as long they like?
MPAs break back buttons all the damn time, I'd say more often than SPAs do.
Remember the bad old days when websites would have giant text "DO NOT USE YOUR BROWSER BACK BUTTON"? That is because the server had lots of session state on it, and hitting the browser back button would make the browser and server be out of sync.
Or the old online purchase flows where going back to change the order details would completely break the world and you'd have to re-enter all your shipping info. SPAs solve that problem very well.
Let's think about it a different way.
If you are making a phone app, would you EVER design it so that the app downloads UI screens on demand as the user explores the app? That'd be insane.
As for phone apps these are undeniably a step backwards from desktop apps, web apps and every other kind of app. On the web you can deploy 100 times a day, waiting for the app store to approve changes to your app is like building a nuclear reactor in comparison.
All the time you get harassed in a physical store or a web site to "download our mobile app" and you know there ought to be a steaming pile of poop emoji because the mobile app almost always sucks.
One of the great answers to the app store problem is to move functionality away from the front end into the back, for instance people were looking to do this with chat bots and super apps back in 2017 and now that chatbots are the rage again people will see them as a way to get mobile apps back on internet time.
Yeah, state mutation triggered by GET requests is going to make for a bad time, SPA or MPA. Fortunately enough of the web application world picked up enough of the concepts behind REST (which is at the heart of all web interaction, not just APIs) by the mid/late 00s that this already-rare problem became vanishingly rare well before SPAs became cancerous.
> going back to change the order details would completely break the world and you'd have to re-enter all your shipping info. SPAs solve that problem very well.
The problem is entirely orthogonal to SPA vs MPA.
> If you are making a phone app, would you EVER design it so that the app downloads UI screens on demand as the user explores the app?
It's not only EVER done, it's regularly done. Perhaps you should interrogate some of the reasons why.
But more to the point, if it's bad, SPAs seem to frequently manage to bring the worst of both worlds, a giant payload of application shell and THEN also screen-specific info, all for reasons like developer's unfortunately common ability to understand that both JSON and HTML are perfectly serviceable data exchange formats let alone that the latter sometimes has advantages.
Content in the app is reloaded, sure, but the actual layout and business logic? Code that generally changes almost never, regenerated on every page load?
I know of technologies that are basically web wrappers that allow for doing that to bypass app store review processes, but I'd be pissed if an alarm clock app decided to reload its layout from a server every time I loaded it up!
The SPA model of "here is an HTML skeleton, fill in the content spaces with stuff fetched from an API" makes a ton more sense.
The application model, that has been in use for even longer, of "here is an application, fetch whatever data you need from whatever sources you need" is, well, a fair bit simpler.
Everyone is stuck with this web mindset for dealing with applications and I get the feeling that a lot of developers now days have never written an actual phone or desktop application.
> But more to the point, if it's bad, SPAs seem to frequently manage to bring the worst of both worlds, a giant payload of application shell and THEN also screen-specific info, all for reasons like developer's unfortunately common inability to understand that both JSON and HTML are perfectly serviceable data exchange formats (let alone that the latter sometimes has advantages).
I've seen plenty of MPAs that consist of multiple large giant mini-apps duct taped together.
Shitty code is shitty code!
Parentheticals added.
Oh, and then request scope wasn't good enough because you needed to do a post-redirect-get? I will say that I do not think MPAs for web applications were the good old days.
I’m just so miffed that it can end up necessitating roping in so much BS. Mind you, not necessarily in this example. Things like HTMX excite me. And, on the other side, things like Next.js and Remix that IMO are a breath of fresh air, even if they might not ultimately be heading in the right direction (I genuinely have no idea).
Good luck forcing users to download 50MB before they can use your web app.
The web and mobile/desktop apps are two totally different paradigms with different constraints.
It was even worse when the page didn't warn you, but would lose state all the same!
You could do some client side caching with local page data, but just keeping it present and requesting updates to it only is vastly superior.
Thats honestly one place SPAs shine, where there's a relatively expensive request that provides data and then a lot of actions that function on some or all of that data transiently.
That is, it may seem a fine optimization, but has led to a fairly bloated experience.
I presume you are thinking of rendering? But, again, that is largely done client side in both cases.
As a simplisit ecanple, imagine an app which on login has to do an expensive query which takes five seconds to return because of how intensive it is on the back end. If you can just redisplay the data that's already in memory on the client, optionally updating it with a much less expensive query for what's changed recently, then you're saving about five seconds of processing time (and client wait time) by doing so.
Yiu could use localStorage to do something similar without it being a SPA, but that's essentially opting into a feature that serves a similar need.
Client side caching is a strong point of SPAs, so it makes sense that a use case that can leverage that heavily will have benefits.
Now, I will grant that it does less. Probably lacking a lot of the "presence detection" that is done in the thick client. Certainly lacking a lot of the newer ad stuff they are pushing at.
But the rest could be offset by a very basic N-tier application where the "envelope" of the client HTML is rather cheaply added to any outgoing message. And the vast majority that goes into "determining what data is being sent, being able to just redisplay the data you have when you browse back to the main page instead of request it again, [etc.]" will probably be more identical than not between the options.
Now, I grant that some of the newer history API makes some tricks a bit easier for back button changes to work. Ironically to the point, is that gmail is broken for back button usage. So... whoops.
I would argue that Google has thrown a bunch of engineering talent at it to optimize the problem as much as it can be for a web interface, and that Gmail is a bad example of a a SPA mail client, as it's more a combined mail client and IMAP server (really a custom designed mail store) all rolled into one. Whether Gmail itself really uses more or not is somewhat irrelevant to whether a mail client in general leans into the benefits a SPA provides. This is what I was talking about here.[1]
That said, whether it uses less resources is a tricky question. Sometimes there's algorithmic wins that overall reduce the total work done, and I don't doubt Gmail leverages some of those, but it's also just a huge amount of caching, whether in the browser or in a layer underneath. The benefit of a SPA is that you can customize the caching to a degree for the application in the client without having to have an entire architectural level underneath designed to support the application. For anything at scale, having that layer underneath is obviously better (it's custom fit for the needs of the application and isn't susceptible to client limitations), but it's also very engineering intensive.
My guess is that Gmail puts a very large amount of cache behind most requests, and is just very, very good about cache invalidation. Or they've got the data split across many locations so they can mapreduce it quickly and efficiently (but tracking where those places are will necessitate some additional resource usage).
In the end, you need caching somewhere. You can do it on the server side so that you have full control over it but you have to pay for the resources, or you can do it on the client side with some limits on control and availability, but you don't use your own resources. SPAs make client side caching more reliable in easier to deal with in some cases, because the working state of the client isn't reset (or mostly reset) on every request.
Sure, gmail optimizes for this heavily so it's fast, but it's still one of the most intensive things you can do for an app like that, so reducing the amount of times you need to do that is a huge win for any webmail. If you've ever used a webmail client that's essentially just an IMAP client for a regular IMAP account, you'll note that if you open a large inbox or folder it's WAY slower than trying to view an individual message, most times, for what are obvious reasons of you just think of a mailbox as a database of email and the operations that need to happen on that database (which it is).
If clicking on an individual message is a new page, that's fine, but if going back to the main view is another full IMAP inbox query, that's incredibly resource intensive compared to having it cached in the client already (even if the second request is cached in the server, it's still far more wasteful than not having to request it again).
The return of the "backend frontender" is also a non happening. The bar is now much higher in terms of UX and design, and for that you really need frontend specialists. Gone are the days when the backend guys could craft a few html templates and call it a day, knowing the design won't change much, and so they would be able to go back to DB work.
ie. "I don't live in a rural area, but that's fine, nobody who matters lives there."
It is entirely possible to have a MPA application that makes calls to the back end to retrieve more data. Especially for things like a static page (cached) with some dynamic content on it. My problem is when people convert an entire site to a Single Page (SPA). When I click to go from the "home page" to a "subsection page", it makes sense to load the entire page. When I click to "see more results" for the list of items on a page, it seems reasonable to load them onto the page.
Side note: If I scroll down the page a few times and suddenly there's 8 items in the back queue, you're doing it wrong. That drives me bonkers.
Plus we now get the benefit of people trying to "replace" built in browser functionality with custom code, either
The SPA broke it... Back button broken and a buggy custom implementation is there instead? Check.
or
They're changing things because they're already so far from default browser behavior, why not? ... Scrolling broken or janky because the developer decided it would be cool to replace it? Check.
There is a time and place for SPA (mail is a great example). But using them in places where the page reload would load in completely new content for most of the page anyways? That's paying a large cost for no practical benefit; and your users are paying some of that cost.