Remix.run Logo
friendzis 10 hours ago

Nothing loaded from the web should be able to fiddle with any browser behavior, yet here we are.

least 10 hours ago | parent | next [-]

The History API is pretty useful. It creates a lot of UX improvement opportunities when you're not polluting the stack with unnecessary state changes. It's also a great way to store state so that a user may bookmark or link something directly. It's straight up necessary for SPAs to behave how they should behave, where navigating back takes you back to the previous page.

This feels like a reasonable counter-measure.

hnlmorg 10 hours ago | parent | next [-]

Yeah but all of this is a symptom of a broader problem rather than reasons why the history API is useful.

SPAs, for example, require so many hacks to work correctly that I often wonder to myself if they’re not really just a colossal mistake that the industry is too blinded to accept.

arcfour 9 hours ago | parent | next [-]

As a user, I really don't care about the supposed purity or correctness of a website's tech stack. When I click "back" I want to go back to what I think the previous page was.

hnlmorg 7 hours ago | parent [-]

As a user, I don’t really care about the building materials used in construction. But that doesn’t mean builders should cut corners.

arcfour an hour ago | parent [-]

A building collapse and a poorly built website UI are completely different in terms of actual risk.

hnlmorg 16 minutes ago | parent [-]

I’d agree with you if laziness wasn’t endemic in software engineering. But we constantly see people’s PII leaked on the internet, accounts hacked and money stolen, due to piss poor safeguards in the industry.

And yes, this is a different issue, but it’s another symptom of the same problem. Tech businesses don’t give a shit, and developers make excuses about how it’s not life or death. Except our bad choices do still negatively affect people’s lives even if we try to convince ourselves it doesn’t.

boomskats 9 hours ago | parent | prev [-]

Could you provide some examples of the hacks you're referring to?

TeMPOraL 9 hours ago | parent | next [-]

State management, URL fragment management, reimplementing basic controls...

One that I hate the most is that they first reimplement tabular display with a soup of divs, then because this is slow as a dog, they implement virtualized display, which means they now need to reimplement scrolling, and because this obviously breaks CTRL+F, they end up piling endless hacks to fix that - assuming they bother at all.

The result is a page that struggles to display 100 rows of data. Contrast that with regular HTML, where you can shove 10 000 rows into a table, fully styled, without noticeable performance drop. A "classical" webpage can show couple megabytes worth of data and still be faster and more responsive than typical SPA.

boomskats 8 hours ago | parent [-]

Sounds like you're referring to some specific examples of poorly implemented apps rather than the concept of SPAs as a whole.

For your example, the point of that div soup is that enables behaviours like row/column drag&drop reordering, inline data editing, realtime data syncing and streaming updates, etc. - there is no way to implement that kind of user experience with just html tables.

There's also huge benefit to being able to depend on clientside state. Especially if you want your apps to scale while keeping infra costs minimal.

I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.

And to be clear, I'm not saying that people building SPAs when all they needed was a page showing 10,000 rows of static data isn't a problem. It's just a people problem, not an SPA problem.

hnlmorg 7 hours ago | parent | next [-]

> all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.

Except they had been solved in other ways and the problem was people insisted on using web technologies to emulate those other technologies even when web technologies didn’t support the same primitives. And they chose that path because it was cheaper than using the correct technologies from the outset. And thus a thousand hacks were invented because it’s cheaper than doing things properly.

Then along comes Electron, React Native and so on and so forth. And our hacks continue to proliferate, memory usage be damned.

friendzis 6 hours ago | parent | next [-]

> And they chose that path because it was cheaper than using the correct technologies from the outset

No, otherwise they would not need all those hacks. Web stack makes it cheap (fast and easy) to build an MVP, but since the very primitives required to fully implement requirements are not even there, they end up implementing tons of ugly hacks held by duck tape. All because they thought they could iterate fast and cheap.

It's the same story with teams picking any highly dynamic language for an MVP and then implementing half-baked typing on top of it when the project gets out of MVP stage. Otherwise the bug reproduction rate outpaces fixing rate.

yoz-y 6 hours ago | parent | prev [-]

Having done native and web frontends, they are different.

I prefer the capabilities of native frameworks but I prefer the web box model.

Sizing stuff is native frameworks is nice until it isn’t.

hnlmorg 4 hours ago | parent [-]

I’ve done both too. And I honestly don’t like the box model.

But I will admit I’ve focused more on desktop than mobile app development. And the thing about sizing stuff is it’s a much easier problem for desktop than mobile apps, which are full screen and you have a multitude of screen sizes and orientations.

phkahler 3 hours ago | parent | prev | next [-]

>> I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.

Any other way? Just build a web app with emscripten. You can do anything.

For a while GTK had an HTML5 backend so you could build whole GUI apps for web, but I think it got dropped because nobody used it.

friendzis 6 hours ago | parent | prev [-]

> rather than the concept of SPAs as a whole.

This is the whole concept of the SPA - make a page behave like multiple pages. The premise itself requires breaking absolutely everything assuming that content is static.

> There's also huge benefit to being able to depend on clientside state. Especially if you want your apps to scale while keeping infra costs minimal.

Um... I'm old enough to remember the initial release of node, where the value proposition was that since you cannot trust client data anyway and have to implement thorough checking both client and server side, why not implement that once.

> I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.

Let me introduce you to our lord and savior native app

riskable 2 hours ago | parent | prev [-]

If you don't manage the history properly in your SPA, pressing the back button could take the user out of the app entirely.

If you don't let web developers manage history/state like this, we'd be going back to the inefficient world of, "every forward/back movement loads a whole page." (With lots of unnecessary round trip messages between the client and server while the user waits for everything to load).

Basically, the ability to manage history is a user-centric feature. It makes the experience better for them.

teo_zero an hour ago | parent [-]

> If you don't manage the history properly in your SPA, pressing the back button could take the user out of the app entirely.

Yes. And that should be the default behavior: browser buttons should take you through the browser's history. If you keep a in-app state and want the user to navigate through it, you should provide in-app buttons.

Nobody complains that the browser's close button quits the browser instead of the app it's showing, or that the computer's power button shuts down the whole OS and not only the program in the foreground.

Users must be educated. If they have learned that left means "back" and right means "forward", that a star (sometimes a heart) means "remember this for me", and that an underlined checkmark means "download", then understanding the concept of encapsulation shouldn't be too much for them.

TeMPOraL 9 hours ago | parent | prev [-]

> It's also a great way to store state so that a user may bookmark or link something directly.

Can you unpack this please? AFAIK history stack is not preserved in the URL, therefore it cannot be preserved in a bookmark or a shared link.

QuantumNomad_ 8 hours ago | parent | next [-]

Probably referring to using pushState (part of the History API) to update the URL to a bookmarkable fragment URL, or even to a regular path leading to a created document.

https://developer.mozilla.org/en-US/docs/Web/API/History/pus...

> The new history entry's URL. Note that the browser won't attempt to load this URL after a call to pushState(), but it may attempt to load the URL later, for instance, after the user restarts the browser.

least 24 minutes ago | parent | prev [-]

Sure. I'm not speaking about preserving the full history stack in the URL, just storing state. Apologies in advance if my explanation for what I mean is something you already understand.

This can be as simple as having a single checkbox with a checked/unchecked state.

when you load the webpage, the javascript can pull in the url parameters with URLSearchParams (https://developer.mozilla.org/en-US/docs/Web/API/URLSearchPa...). If the url parameter you set is set to 'on' then the checkbox, which is by default unchecked, can be set to on.

You have your checkbox:

    <input type="checkbox" id="check">
And then you have your javascript:

    const check = document.getElementById('check');
  
    // get state of checkbox from URL parameter
    check.checked = new URLSearchParams(location.search).get('state') === 'on';
    
    // add event listener to call history api to alter the URL state.
    check.onchange = () => { history.replaceState(null, '', check.checked ? '?state=on' : '?state=off'); };

The history.replaceState() replaces the URL in your history with the one including the URL parameter, so if a user were to bookmark it, it would store that and reload it when they revisit the webpage.

If I used history.pushState(), each time I clicked on the checkbox, a new item would be added to the stack. for a checkbox this is almost certainly a bad idea because your browser history is going to be polluted pretty quickly if you happen to click it multiple times.

pushState can be useful when it matches the user expectations, though, like if it is an SPA and the user clicks on an internal link to another section of the site, they'd expect to be able to go back to the previous page, even though we're still on the same actual html page.

So you would not be preserving the entire history stack. You can sort of do this by encoding state changes into another url parameter, but the behavior isn't entirely consistent between browsers. It also does require, as far as I know, an explicit action from the user for it to actually affect their navigation. So a website couldn't just add 1000 entries to the user's history on load without some explicit interaction on the web page.

Once the user interacts, though, it does seem like it opens up a lot of opportunity to abuse it, intentionally or not. You can asynchronously push thousands of entries into the browser history without blocking interactivity of the site. you can even continue to push state to the URL from other inputs while doing so.

optionalsquid 10 hours ago | parent | prev [-]

It should be opt-in per website, per feature, because IMO it can be quite useful in some cases. Like clicking back on a slide-show bringing you to the overview page, instead of only going back one slide

lxgr 5 hours ago | parent | next [-]

> clicking back on a slide-show bringing you to the overview page

That behavior is expected in exactly one case (assuming slides, not the whole presentation, are modeled as a page each): If I navigated to that specific slide from the overview.

In any other scenario, this behavior amounts to breaking my back button, and I'll probably never visit the site again if I have that choice.

arcfour 9 hours ago | parent | prev [-]

Opt in features are a great way to increase user frustration and confusion. See the whole new geolocation API they had to make for browsers since people would perma-deny it reflexively and then complain that geolocation features weren't working.

optionalsquid 6 hours ago | parent [-]

That's a good point, though I'm not familiar with the (changes to the) geolocation API you mention. Do you have any recommendations for reading up on that development?

arcfour an hour ago | parent [-]

Sure, I should have said geolocation element, since the original API still exists and is used: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...