Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I disagree, the problem with an SPA is that now you have two places where you manage state (the backend and the frontend). That gives you much more opportunity for the two places to disagree, and now you have bugs.


You had to manage state on the frontend even before spa though, if you wanted anything but the most basic experience.


No you really don’t. I’ve worked on exceptionally complex legacy applications with essentially no state in the front end. At most, you’re looking at query parameters. You just make everything a full page reload and you’re good to go.


So you make incrementing a counter a full page reload?


You don't need an SPA to handle incrementing a counter. If a page needs dynamic behavior you add JS to it, whether it's just adding an in-memory counter or an API call to store and retrieve some data. It's not difficult to write JavaScript.

The problem with SPAs is that they force having to maintain a JS-driven system on every single page, even those that don't have dynamic behavior.


> You don't need an SPA to handle incrementing a counter. If a page needs dynamic behavior you add JS to it, whether it's just adding an in-memory counter or an API call to store and retrieve some data. It's not difficult to write JavaScript.

I agree with this. Sprinkle in the JS as and when it is needed.

> The problem with SPAs is that they force having to maintain a JS-driven system on every single page, even those that don't have dynamic behavior.

I don't agree with this: SPAs don't force "... having to maintain a JS-driven system on every single page..."

SPA frameworks do.

I think it's possible to do reasonably simple SPAs without a written-completely-in-JSX-with-Typescript-and-a-5-step-build-process-that-won't-work-without-25-npm-dependencies.

I'm currently trying out a front-end mechanism to go with my high-velocity back-end mechanism. I think I've got a good story sorted out, but it's early days and while I have used my exploratory prototype in production, I've only recently iterated it into a tiny and neat process that has no build-step, no npm, and no JS requirement for the page author. All it uses is `<script src=...>` in the `<head>`, with no more JS on the rest of the page.

Very limited though, but it's still early days.


A codebase doesn't need that toolset to be an SPA. An SPA is just a website where all the site's functionality is done on the "root page", and it uses JS to load the data, handle navigation, etc. Doesn't matter whether that's all done through React in TypeScript and compiled by Vite or by handrolled JavaScript fetched in .js files.


> A codebase doesn't need that toolset to be an SPA.

That's kinda the goal I'm trying to reach. If you know of any SPA that doesn't come with all the baggage and only uses `<script src=...>`, by all means let me know.


That's still state on the frontend, which the commenter claimed sites don't need.


True, I shouldn't have said in memory. As the GP mentioned, you can store the counter value in a URL param. There are ways to achieve dynamic behavior without having to load or store values into JS memory.


That is more work both for the developers and the servers though. You need to re-render the whole page every change, rather than make a local change (or a tiny request if it needs to persist)


You misunderstood what I was saying. I was saying that you could write some plain old JS to catch an event on incrementing and updated the URL and the UI, and some JS to get the data from the URL on page load to set the UI. No new server render, and that's maybe 5 minutes of writing JavaScript code (compared to, say, setting up react project and instantiating that whole beast from the page root until reaching the specific UI element that needs to be dynamic).


What's the business usecase for incrementing a counter?

We can sit here all day and think up counterexamples, but in the real world what you're doing 99% of the time is:

1. Presenting a form, custom or static.

2. Filling out that form.

3. Loading a new page based off that form.

When I open my bank app or website, this is 100% of the experience. When I open my insurance company website, this is 100% of the experience. Hell, when I open apartments.com, this is like 98% of the experience. The 2% is that 3D view thingy they let you do.


> What's the business usecase for incrementing a counter?

Notification count in the top right?

Remaining credit on an interactive service (like the ChatGPT web interface)?

So, maybe two(!) business use-cases out of thousands, but it's a pretty critical two use-cases.

I agree with you though - do all normal HTML form submissions, and for those two use-cases use `setInterval` to set them from a `fetch` every $X minutes (where you choose the value for $X).


Notification incrementing is not purely client-side state though. It's triggered by an event coming from a server. Eg let's say you're on a product page and you click 'Add to Cart'. You want the cart icon's counter badge on the top right corner of the page to increment. With eg htmx when you click 'Add to Cart' we send a request to the server, it updates the cart state in the backend, then sends an HTML fragment response that updates the necessary parts of the page, including the cart item counter badge.


In my experience it's just exceedingly rare to require this. My insurance company website has a notification thing, and it's actually static. You need to refresh the page, and considering how few and far between notifications are, and how common refreshes are, it works fine.

There's an entire domain of apps where you truly need a front-end. Any desktop-like application. Like Google Sheets, or Figma. Where the user feedback loop is incredibly tight for most operations.


Let's be honest -- the alternative is an API call with poor or no error-handling with the brilliant UX of either hanging with an endless loading indicator, or just flat out lying that the counter was incremented...


> or just flat out lying that the counter was incremented...

Which is what HN does and it sucks. It's very common for me to vote on a couple things and then after navigating around I come back to see that there are comments that don't have a vote assigned.

Of course the non-JS version would be even more annoying. I would never click those vote buttons if every vote caused a full page refresh.


That sounds like the most basic of experiences...


Not between page loads.


You absolutely did. It was common practice to stuff things in cookies or query strings to retain state between trips to the server so that some JS could do its job.

Every form also normally ends up duplicating validation logic both in JS for client-side pre-submit UX and server-side with whatever errors it returns for the JS to then also need to support and show to the user.


Right, but validation logic and state transferred by the server isn't in-memory state. The fact that the pages completely reload on each request clears a lot of cruft that doesn't get cleared on pages whose lifetime is tens or hundreds of views.


Every SPA I come across, especially when using React, uses persistent state so that in-memory changes are synced to cookie/localStorage/server so they survive refreshes. Every popular state management library even supports this natively. And all of that state combined still requires less memory than any of the images loaded, or the JS bundles themselves.


I absolutely loathe that. State is the source of most bugs. If the page crashes then refreshing it should clear out the state and let me try again.

Anecdotally, it seems like I encounter a lot more web apps these days where refreshing doesn’t reset the state, so it’s just broken unless I dig into dev tools and start clearing out additional browser state, or removing params from the URL.

Knock it off with all the damn state! Did we forget the most important lesson of functional programming; that state is the root of all evil?


Minimizing state simplifies the codebase but it’s a trade off.

There are times the user experience is just objectively better with more state, and you have to weigh the costs.

If I am filling out a very long form (or even multi-page form) I don’t really want all that state lost if I accidentally refresh the page.


I can remember vastly more instances where I've been frustrated as a user of an app or website by losing state, than remember state.


Unless you can guarantee RTT under 100ms, you have to manage some state on client side, else your UI will feel sluggish.


I’d rather have sluggish UI with proper feedback than potentially inconsistent states which I often experience with modern SPAs. At least that represents reality. Just today I was posting an ad on the local classifieds page, and the visual (client) state convinced me that everything was fast and my photos are uploaded. Turned out all state was lost and never reached the server, and I had to redo everything again.


It’s trivial to achieve under 100ms in the US with even just one server.

Most companies aren’t international.


Without keep-alive, any HTTPS request requires multiple round trips to complete.


Fortunately every browser made in the last 25 years supports keepalive. e.g. Firefox (and according the the reporter of this bug, Chrome) won't even let you disable it[0].

[0] https://bugzilla.mozilla.org/show_bug.cgi?id=879002


Barring the interactivity SPAs will also end up talking to server anyway. So even SPAs will feel sluggish in a high latency env.


Phoenix Liveview works pretty good without client side state. Sure if you just have a toggle mobile menu you might sprinkle some JS for it but other state lives in the server and the delta is sent to the client via websockets


Client-server model is known for decades, state management between them isn’t hard.


Who says your backend needs to manage state?


You don't have a database?




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

Search: