Live data from Hacker News

Building a robust frontend using progressive enhancement

gov.uk

161–168 of 168 posts

Re: Building a robust frontend using progressive enhancement

#161
post #52

OMG it feels so good to not be the lone voice in the woods. I would say about 3/4 of my frustrations as a user are from sites that should have simply been built with HTML + CSS and minimal Javascript. The front end community most days feels like a jobs program.

You aren't alone, I'm a technical director and even I can't win this battle. We have a ton of complexity on what could be a simple SSR site, but frontend devs don't like writing anything but SPAs, so it's hard to change.

I get it. And to be clear, I have seen SPAs that justified their existence. I just feel very strongly that for most of the apps I use on a regular, daily basis (email, messaging, newspapers, bank, etc), SPAs are just totally unnecessary.

A hill I will die on: the users NEVER asked for them. The UI community likes to pretend otherwise, but the users never asked for SPAs. What users want is the simplest, clearest and fastest possible experience, that changes only gradually and only when necessary. SPAs often stumble on simple and clear, and straight up explode on fast.

Re: Building a robust frontend using progressive enhancement

#162
post #28

Good advice, but > - users of assistive technology would be unaware of changes in context, for example when moving to a new page > - it would fail to handle focus when moving between pages > - the user would be unable to navigate using the back or forward buttons in their browser > - users would be unable to recover from an error, for example if there is an interruption to their network connection These aren’t strict…

You kind of get it out of the box with plain old HTML though. Once you get into SPA territory you’re reinventing a lot of wheels to get back to parity, or replacing native functionality with JS alternatives. Consider multi-page forms: how many SPAs just store all of that in memory and then make one request at the end? Without JS, the BE would be saving the state for each step so you could come back to the form later…

You can easily store intermediate state in sessionStorage or localStorage and prevent all the unneeded requests to the server just for moving between steps.

Re: Building a robust frontend using progressive enhancement

#163

Earlier quoted context omitted.

> could be a simple SSR site, but frontend devs don't like writing anything but SPAs It might be worth asking why that is. I used to write a ton of SSR'ed pages back when that was really the only option we had (before people introduced jQuery and AJAX), then I wrote SPAs (mostly Angular & React), then again SSR'ed websites (Java/Spring/JSP with a ton of more-or-less vanilla JavaScript) and now I've been on a Vue-base…

You're arguing against something different, though: I agree you shouldn't do components with CSS/jQuery, components should be self-contained. I'm arguing against SPAs , where the state of the user's browsing is replicated on the frontend as well, with all the complexity this entails. Isn't there a good component framework we can use, and that's it? I want to be able to say and have it work, without having to have a w…

> I'm arguing against SPAs, where the state of the user's browsing is replicated on the frontend as well

What state exactly are you referring to? I'm not trying to play dumb, I'm genuinely curious because in my experience there can be "good" and "bad" state in the frontend (where "good" roughly translates to "inherent to the problem").

> I want to be able to say and have it work, without having to have a whole SPA attached to my components library

A carousel sounds like a great example for something that could be standalone. However, what if 1) the data shown in the carousel needs to be loaded lazily (e.g. because the carousel is near the end of the page and loading the data is expensive), and 2) the carousel's display settings (e.g. how many items are shown at once) depend on the content being shown? I recently had to work on exactly this case. Suddenly, your once static carousel component isn't so static anymore and you have to add a bunch of JavaScript, and also state.

> without having to have a whole SPA attached to my components library, with routing, state

Maybe I'm missing something here but pure React/Vue doesn't require your page to be an SPA or to have any routing mechanism at all?

Re: Building a robust frontend using progressive enhancement

#164

Earlier quoted context omitted.

You're arguing against something different, though: I agree you shouldn't do components with CSS/jQuery, components should be self-contained. I'm arguing against SPAs , where the state of the user's browsing is replicated on the frontend as well, with all the complexity this entails. Isn't there a good component framework we can use, and that's it? I want to be able to say and have it work, without having to have a w…

> I'm arguing against SPAs, where the state of the user's browsing is replicated on the frontend as well What state exactly are you referring to? I'm not trying to play dumb, I'm genuinely curious because in my experience there can be "good" and "bad" state in the frontend (where "good" roughly translates to "inherent to the problem"). > I want to be able to say and have it work, without having to have a whole SPA at…

> where "good" roughly translates to "inherent to the problem"

I don't mean per-page state (that one is inherent to the problem, as you say), but cross-page state (the one typically handled by backends, such as authentication, account info, stuff you've done in your current session, etc).

> Suddenly, your once static carousel component isn't so static anymore and you have to add a bunch of JavaScript, and also state.

You're right, all of this is inherent to the problem as well, and you do need state. Generally, however, I haven't found a need for state to cross pages, which is a really good reducer of complexity (things are easier to reason about if every page load starts with a known state).

> Maybe I'm missing something here but pure React/Vue doesn't require your page to be an SPA or to have any routing mechanism at all?

They don't require it, but they make it easy, and that's the default that all frontend development pretty much starts with. Nobody says "hey, do we really need routing?". They start from "the way you make an app is with routing", and now you have a SPA where you just needed components. That's the big problem, and we've had a fair amount of issues with this...

Re: Building a robust frontend using progressive enhancement

#165

Earlier quoted context omitted.

I’ve run into developers that don’t understand how regular HTML forms work and think everything needs a REST call with JSON. Many of them were not young.

Me too, I was devastated. The guy was a super expensive senior react dev. He literally went like: “Wdym multipart form data?”

Sadly, we now have a whole generation of web devs that don't know anything other than SPAs.

Re: Building a robust frontend using progressive enhancement

#166

Earlier quoted context omitted.

> I'm arguing against SPAs, where the state of the user's browsing is replicated on the frontend as well What state exactly are you referring to? I'm not trying to play dumb, I'm genuinely curious because in my experience there can be "good" and "bad" state in the frontend (where "good" roughly translates to "inherent to the problem"). > I want to be able to say and have it work, without having to have a whole SPA at…

> where "good" roughly translates to "inherent to the problem" I don't mean per-page state (that one is inherent to the problem, as you say), but cross-page state (the one typically handled by backends, such as authentication, account info, stuff you've done in your current session, etc). > Suddenly, your once static carousel component isn't so static anymore and you have to add a bunch of JavaScript, and also state.…

> cross-page state (the one typically handled by backends, such as authentication, account info, stuff you've done in your current session, etc).

Yeah, that one is a different beast. We've been trying to keep it very simple in our SPAs lately: Account information & other backend data get retrieved from the backend upon page load (its all one big GraphQL query) and then it ends up in the GraphQL cache. If we then do a SPA-like soft page switch, that cache will speed up the next page's page load. However, the next page's GraphQL query will still be fired (it will likely need some other data that's not in the cache yet, anyway) which ensures the UI stays consistent with the backend state. In other words: The client-side cache is merely a mirror of the backend state and its presence or absence only affects loading behavior. There is no cross-page state beyond that (almost, see below).

> Generally, however, I haven't found a need for state to cross pages, which is a really good reducer of complexity (things are easier to reason about if every page load starts with a known state).

Agreed! If I do have a bit of client-only state which I'd like to persist (e.g. some kind of user selection / filter / …), then I simply encode it in the URL. Components then don't keep their own (mutable) copy of that state but simply mutate the URL to modify state. In that way, I end up with a one-to-one correspondence between URLs and UI states.

Re: Building a robust frontend using progressive enhancement

#167

Earlier quoted context omitted.

> where "good" roughly translates to "inherent to the problem" I don't mean per-page state (that one is inherent to the problem, as you say), but cross-page state (the one typically handled by backends, such as authentication, account info, stuff you've done in your current session, etc). > Suddenly, your once static carousel component isn't so static anymore and you have to add a bunch of JavaScript, and also state.…

> cross-page state (the one typically handled by backends, such as authentication, account info, stuff you've done in your current session, etc). Yeah, that one is a different beast. We've been trying to keep it very simple in our SPAs lately: Account information & other backend data get retrieved from the backend upon page load (its all one big GraphQL query) and then it ends up in the GraphQL cache. If we then do a…

Yeah, that's a great way to do it, and that way your URLs always work properly as well. Maybe our frontend devs just need a bit more discipline...

Re: Building a robust frontend using progressive enhancement

#168
post #28

Good advice, but > - users of assistive technology would be unaware of changes in context, for example when moving to a new page > - it would fail to handle focus when moving between pages > - the user would be unable to navigate using the back or forward buttons in their browser > - users would be unable to recover from an error, for example if there is an interruption to their network connection These aren’t strict…

You kind of get it out of the box with plain old HTML though. Once you get into SPA territory you’re reinventing a lot of wheels to get back to parity, or replacing native functionality with JS alternatives. Consider multi-page forms: how many SPAs just store all of that in memory and then make one request at the end? Without JS, the BE would be saving the state for each step so you could come back to the form later…

Yes, hence why it’s good advice.
Post reply on HN