Comment by hombre_fatal

4 years ago

Exactly. I've been in the position various times where I'm embedding a JS app on a page to help the user do something highly interactive, usually creating/editing content. And then as it's expanding to integrate with other things on the site, I start to wish more of the site was in the JS-app side of things.

Sometimes I realize a SPA would have simply served the user better, and it doesn't necessarily take much to be in that predicament.

Too many people hate on SPAs by, presumably, just imagining static read-only content like blogs and news. Though I'm also a bit tired of "SPAs suck amirite, HN?"

Put the user first, consider the trade-offs that work towards that goal, and see what shakes out.

The other thing people who hate SPAs need to think about is that rendering blogs/news/static sites isn't a problem that developers really work on anymore. Businesses will just pick from the huge pile of existing CMSs or hosted solutions because it's easier and cheaper. So if you're wondering why all these developers are building SPAs, it's because we're building custom applications, not blogs.

I think the fundamental issue with SPAs is that it's building on multiple levels of technology that fundamentally weren't designed to support being a single page application.

The browser <-> multiple pages paradigm is pretty much how the web evolved, so SPA's just end up being one giant hack to get everything working.

UWP/WPF/any other desktop app framework demonstrates how easy developing a 'single page application' can be without all the cruft you have to add to make a SPA work because it's actually a sort-of-massive-workaround.

  • Well, the browser has certainly evolved past the point of SPAs being nothing but a hack. The browser has evolved into a heavily generalized application environment, as much as we may want to bemoan that. A good web client can surely demonstrate this.

    It's certainly true that you don't get to lean on built-in features like history support, but that's why you can now drive history with Javascript. And all sorts of other things. And if you're smart, you're using a solution that handles these things for you.

    Rich client development is always hard—on any platform—, and you always make concessions for the platform you're on. I certainly have to when I'm building iOS apps. But I see no reason for this to dissuade you if you can push a better UX to the user.

    As tried-and-true as server-rendered architecture might be, there are all sorts of things it will never be able to do no matter how much of a hack you think web client development might be. Software is a hack. And at the end of the day, your users may remain unconvinced when you preach about what the browser was "meant to do" when they begin coveting a richer experience.

    That's something that's often left by the wayside when we discuss these things. We talk about technical superiority and become prescriptive about what we think technology is for. While fun thought exercises as craftspeople, we too seldom talk about delivering value. If leaning into the historical nature of the browser supporting HTML pages over the wire helps you build a better experience, that's great. But that's not the only option you have today.

    • > Rich client development is always hard—on any platform—, and you always make concessions for the platform you're on. I certainly have to when I'm building iOS apps. But I see no reason for this to dissuade you if you can push a better UX to the user.

      I think the difference is how much you as a developer have to "fight" the platform. Having to implement history management yourself very much qualifies as "fighting" to some extent in my eyes… continuing with native platforms as an example, that sort of thing just isn't necessary in most cases – like with iOS, 99% of your "history" management comes for free with some combination of UINavigationController and view controller presentation, assuming the use of UIKit.

      3 replies →

  • At least since HTML5 and CSS3 and ES6 (so many years already) these technologies are made for SPAs. There aren't many better UI frameworks, and WPF isn't that by a long shot.

    • I wouldn't really say that - CSS3 was made in 1999 so was hardly made for SPAs.

      Additionally HTML5 wasn't really 'made for' SPAs, it added features to HTML which could help support SPA's but it's main design decision was to be 100% backwards compatible with the older HTML spec. HTML5 is made for SPAs the same way that a stretched limo is made for commuting.

      1 reply →

  • In my opinion, UWP/WPF/aodaf makes it easy because it just doesn't implement the things a user is used to in a browser (bookmarkability, back button, ...).

    If you ignore those things in your SPA, much of the "cruft" is negligible.

    • This is pretty in line with grandparent’s comment in that the browser was simply not made for this - aka SPAs are sort of a hack on the traditional page-based approach.

    • Many desktop apps have back buttons, and of course mobile apps always have them. They're also more reliable; there is no desktop/mobile equivalent of the "warning: need to re-POST this form" problem.

      As for bookmarks, that's semi-right, but the web platform conflates the back button with bookmark-ability in ways that are quite confusing. If you want the back button to get the user out of your settings screen, then you must push a new URL onto the history stack using JavaScript, but then if the user bookmarks your site they'll bookmark the settings screen specifically even though that's very unlikely to be what they wanted. Non-web apps that have enough content to need something like bookmarks often implement a similar mechanism that's more predictable, albeit less general.

      The OPs article is really a common lament amongst web developers - they're (ab)using a tool that was never meant for what they're using it for. It's a real and very serious problem in our industry.

      The whole SPA vs multi-page dichotomy really emerges because the web doesn't have sufficiently rich, modular or low level APIs. If you look at non-web frameworks like iOS or Java then you get a huge number of APIs (usually classes) tackling the low levels of a problem, then more classes building on the lower levels to give you higher level solutions. Those classes can usually be customized in many different ways, so the amount of control a developer has is enormous. If you start with a high level helper class and find you can't customize it to meet your needs, you can reimplement it using the lower level building blocks.

      The web isn't like this. Web APIs are an absolute pigs ear of very high level function calls and classes designed in more or less random ways to quickly hack together a solution to whatever need a browser maker had at the time. HTML5 supports peer-to-peer video streaming and augmented reality but not a virtualized table view. In many cases it's obvious that little or no thought went into the APIs, e.g. XMLHTTPRequest has nothing to do with XML, you can open a URL for a custom URL handler but not detect if that URL will work ahead of time, nor even if opening that URL worked once you try it, and so on. Instead of starting with low level APIs and composing them into high level APIs, browsers start with high level APIs and then introduce entirely orthogonal low level APIs decades later, or never.

      These sorts of problems just don't occur when writing desktop apps with professionally designed frameworks - even in the rare cases that you hit some limit of the framework, you can (these days) just patch it directly and ship a fixed version with your app. If you hit a problem in the browser you're just SOL and have to hack around it.

      Our industry needs to reinvigorate desktop apps. Attempting to convert browsers into Qt/Java/.NET competitors has:

      a. Made HTML5 unimplementable, even by Microsoft. It's not so much a spec anymore as a guide to whatever Chrome happens to do on the day you read it (hopefully).

      b. Created tons of security holes.

      c. Yielded an atrocious and steadily decaying developer experience.

      1 reply →

Setting limits for future features to keep the code base clean and manageable is something developers could be more vocal about.

Acquiescing to every demand product designers and management throw into the mix is what turns beautiful, easily-maintained codebases into nightmares.

What people are talking about here is writing web apps as a series of small, tightly-coupled spas who manage state within very specific parameters. And that's a great way to build software. Until someone comes in and asks you to draw in the state from one section into two other sections. You have the choice to say a) no and explain why, to b) create a clever "glue" that will be hard to maintain and difficult to explain, or to c) take the time to refactor the code into something more general and complex to allow for the feature on a more abstract level.

Guess which one almost always gets chosen.

The upshot is this: The solution to front-end complexity may not be a technical one, it may not require a new framework or library. It may be a shift in what we expect out of the web. We could always temper our expectations in order to keep our code clean.

  • The end goal of writing code isn't always a "clean and manageable" codebase.

    Likewise the solution to SPAs isn't "say no to features".

    • I'm aware, but the discussion about the failures of spas always center around their failures in maintainable code. So if one's issues with SPAs are codebases becoming unmanageable, the solution won't be technical, it's going to be managerial.

      A start would be devs communicating to product & design what the technical limits are to the current approach so that it informs their decisions.

> Put the user first, consider the trade-offs that work towards that goal, and see what shakes out.

In my experience, every single team I've been part of that was building an SPA was because they put the developer experience and desires first, even if in the mid/long term the dev experience ends up being worse as the project grows.

> Exactly. I've been in the position various times

This is why React is such a popular JavaScript framework of libraries.