7 ms·
I'm starting to wonder whether reactivity (not React specifically) was the originally sin that led to modern UI complexity. UI elements automatically reacting t
by hliyan 7mo ago
I'm starting to wonder whether reactivity (not React specifically) was the originally sin that led to modern UI complexity. UI elements automatically reacting to data changes (as oppposed to components updating themselves by listening to events) was supposed to make things easier. But in reality, it introduced state as something distinct from both the UI and the data source (usually an API or a local cache). That introduced state management. It was all downhill from there (starting with two way data binding, Flux architecture, Redux, state vs. props, sagas, prop drilling, hooks, context API, stateful components vs. stateless components, immutability, shallow copy vs. deep copy, so on and so forth).
- ivanjermakov 7mo agoI still believe immediate rendering is the only way for easy-to-reason-about UI building. And I believe this is why early React took off - a set of simple functions that take state and output page layout. Too bad DOM architecture is not compatible with direct immediate rendering. Shadow DOM or tree diffing shenanigans under the hood are needed.
- hungryhobbit 7mo agoYes! I think there's a lot of armchair web developers in these comments who think they know better: they don't. Meanwhile, those of us that were building web apps with JQuery and other tools prior to React know just how painful "web development without reactivity" actually was.
- Izkata 7mo agoIndeed.. Mostly-static pages with sprinkled-in interactivity were fine (like a table where you could sort the columns), but a full app? I dread having to touch the one page we have that uses Backbonejs+Mustachejs. Also, things like unidrectional data flow are generally considered normal now, but back in that era it was rare. Two-way binding was much more popular, with constant bugs as the app grew. Around 2013 or so I was trying to switch a new page we were building to a very simple form of unidirectional data flow to deal with constant issues (ours issues were mostly losing state, we were all ad-hoc and not using two-way binding) and the other devs just did not at all understand it, constantly sidestepping it without even thinking because jquery made it so easy to touch everything.
- applfanboysbgon 7mo agoI genuinely don't understand why this model is the norm. As a game developer working in my own engine, UI is unbelievably straight-forward: the game has state. The master Render() function draws all of the graphics according to the current state, called at framerate times per second. Nothing in Render() can change the state of the program. The program can be run headlessly with Render() pre-processed out completely. The mental model is so easy to work with. There is a sleep-management routine to save on CPU usage when idle, and dirty logic to avoid re-drawing static content constantly. I feel like the world would save 90% of its GUI development time if it didn't do whatever the fuck reactive UIs are doing.
- hliyan 7mo agoThat reminded me of another complexity: virtual DOM diff.
- croes 7mo agoUI is mostly static. Rendering everything at framerate per second is a huge waste of time and energy.
- Lerc 7mo agoThis was the case back in the days of the Amiga and 68000 Macs. Rendering everything every frame was impossible, the only way to make it work at all was to draw only what was absolutely necessary to depict changes. Then computers got faster, much much faster. It became possible to redraw the whole UI from state every frame without it being a significant cost. At the same time retained user interfaces managed to become more and more costly to do just about anything. I don't think for any particular reason other than computers were fast and they didn't need to do much better. I find it really odd that there are user interfaces that take longer to rearrange their items than it takes for the same CPU to RayTrace a scene covering the same amount of screen area.
- croes 7mo agoJust because computer got much faster doesn’t mean it’s a good idea to make wasteful rerenderings of things that didn’t change.
- mpalmer 7mo agoWhy do you list all of these design patterns as though you have to hold them all in your head at the same time? As though each one made the ecosystem successively worse? UI elements automatically reacting to data changes (as oppposed to components updating themselves by listening to events) That's not so much a lack of statefulness as it is making zero effort to lift your application's data model out of platform-specific UI concerns.
- tobyhinloopen 7mo agoI use Preact without reactivity. That way we can have familiar components that look like React (including strong typing, Typescript / TSX), server-side rendering and still have explicit render calls using an MVC pattern.
- yde_java 7mo agoHow and when do your components update in such an architecture?
- gr4vityWall 7mo agoFrom what I can tell, they do full page reloads when visiting a different page, and use Preact for building UIs using components. Those components and pages then get rendered on the server as typical template engines.
- tobyhinloopen 7mo agoView triggers an event -> Controller receives event, updating the model as it sees fit -> Controller calls render to update views Model knows nothing about controller or views, so they're independently testable. Models and views are composed of a tree of entities (model) and components (views). Controller is the glue. Also, API calls are done by the controller. So it is more of an Entity-Boundary-Control pattern.
- threatofrain 7mo agoCould you show an example?
- _heimdall 7mo agoI'd argue that it was all downhill after we moved away from using HTML as the state representation. Moving state out of HTML and into JS means we now have to walk this ridiculous tightrope walk trying to force state changes back into the DOM and our styles to keep everything in sync. Given that problem, reactivity isn't the worst solution in my opinion. It tries to automate that syncing problem with tooling and convention, usually declaratively. If I had to do it all again though, DOM would still be the source of truth and any custom components in JS would always be working with DOM directly. Custom elements are a great fit for that approach if you stick to using them for basic lifecycle hooks, events, and attribute getters/setters.
- pfraze 7mo agoWasn’t that the Lit framework? It was okay. Like a slightly more irritating version of React. I recall the property passing model being a nasty abstraction breaker. HTML attributes are all strings, so if you wanted to pass objects or functions to children you had to do that via “props” instead of “attributes.” I also recall the tag names of web components being a pain. Always need a dash, always need to be registered. None of these problems broke it; they just made it irritating by comparison. There wasn’t really much upside either. No real performance gain or superior feature, and you got fewer features and a smaller ecosystem.
- spankalee 7mo agoThe point of Lit is not to compete with React itself, but to build interoperable web components. If your app (Hi Beaker!) is only using one library/framework, and will only ever one one in eternity, then interoperability might not be a big concern. But if you're building components for multiple teams, mixing components from multiple teams, or ever deal with migrations, then interoperability might be hugely important. Even so, Lit is widely used to build very complex apps (Beaker, as you know, Photoshop, Reddit, Home Assistant, Microsoft App Store, SpaceX things, ...). Property bindings are just as ergonomic as attributes with the .foo= syntax, and tag name declaration has rarely come up as a big friction point, especially with the declarative @customElement() decorator. The rest is indeed like a faster less proprietary React in many ways.
- neya 7mo agoAbsolutely. Look at facebook today. Back in 2010, everything had just the right amount of interactivity. Because, separation of concerns existed at the language level - HTML for structure and CSS for presentation, JS for everything else. Then some bunch of geniuses decided it would be awesome to put everything together in the name of components. Today, you open facebook, the creators of React - normal drop-down with just a list of barely 5-6 items is a fucking component that makes 10 different requests. I would even argue this unnecessary forced interactivity is what perhaps annoyed users the most as everything always has to "load" with a spinner to the point of the platform being unusable. Same goes for instagram. It's not just that, React is a hot ball of mess. It's not opinionated, so anyone can use anything to do anything. This means if you work with multiple teams, each one uses their own code organisation, state management library and general coding paradigm. Eventually the engineers leave and the new guy decides to do things his own way. I've honestly never seen a company with a great product run over React. Everything always is being re-written, migrated every 3 weeks or straight up is buggy or doesn't work. React is the worst thing to happen to the Javascript ecosystem. The idea is good, but the execution is just piss poor. I mean look at Vue and Svelte, they managed to do it right.
- incrudible 7mo agoIf the html+css+js trifecta was any good for creating UI beyond simple forms, we would not have witnessed the cambrian explosion of ways to do it differently. Reactivity itself was an answer to the pain of using MVC and similar approaches in older GUI toolkits not made for the web. The pain did not stop entirely, of course, because GUI is a complicated and ill defined problem - but I don’t look back fondly to programming without it.
- usrbinenv 7mo agoReact got popular not because of its amazing time-tested ideas (everyone knows they re-engineer everything once every couple years!), but, strictly speaking, because at the time it was released there wasn't any kind of serious SPA or partially-SPA framework for the web and also because JavaScript sucked a lot more at the time (no classes!). Qite is perfectly suitable for complex UIs thanks to its state functionality, you can build pretty complex functionality and UI and not sacrifice user's CPU in the process.
- AlienRobot 7mo agoIn my view, the problem isn't specifically reactivity but the fact that reactivity isn't actually native of the UI toolkit. Instead of HTML, think about GTK or Swing. To add React-style "reactivity" to it, instead of just making a dialog to change the "title" of a document and committing the change when you press OK, you'd need a top-level "App" class that holds all the state, a class for state properties with IDs accessible at runtime which probably would be a variant (accepts any primitive type), a binding class to bind the toolkit's textbox to the App's state "title" property (because you'll probably want to bind a lot of textboxes, so it's easier to separate the code into classes), and then every time the user types something into the textbox, instead of using the toolkit's code that is already written for you which updates the textbox' state directly, you block the state change in an event handler, send the state change to the App class, let the App class figure out the differences between the current state and the new state, and then it calls some callback in the binding class that is responsible for actually changing the text in the textbox to reflect the new App state. You'll probably run into a ton of issues (selections resetting, assistive technologies bugging, etc.) that you'll have to deal with externally somehow. All just to make it do exactly the same thing it would have done anyway. It's like you have a fully autonomous robot and you want to add marionette strings to make it move.
- nogridbag 7mo agoI believe every UI developer that has used frameworks like Swing has reached a point where specific user interfaces, even those that look trivial, become too complex primarily due to things like event handlers. Trying to figure out a simple thing like why a radio box is enabled and is marked dirty may require long debugging sessions where one event handler for component A triggers another event handler for component B, which triggers another event handler, etc. And before you know it, 50 events were triggered just during the initial mounting of the UI. Making sense of it all is maddening. And then said developer does what they think feels right: "I have my state and I simply want all the fields to reflect my state". So they try and rewrite the component into some sort of mini immediate-mode style component. All of the event handlers get wired up a single "layoutComponent" method that tries to call all the UI component setters based on the current state with all the problems you alluded to. I know I've done this type of things numerous times before going back all the way to my first internship, well before React was even a thing. I think modern frameworks solve the reactivity issue this well enough, that it really doesn't matter if the underlying framework is not natively reactive. I will say though that I've primarily used Vue.js where most state is relatively local and we don't try to re-render the world on every input. I think part of the problem with modern dev is likely that React has become the default instead of a simpler framework like Vue.
- ramesh31 7mo agoGive me state management vs. event bus management any day of the week. The former is fully testable and verifiable. You can even formally define your UI as a state machine. With events you are constantly chasing down race conditions and edge cases, and if your data lives seperately in components there is no clean way to share it horizontally.
- usrbinenv 7mo agoJust to clarify: Qite does both events AND state, which I find quite powerful and useful.
- codethief 7mo ago> UI elements automatically reacting to data changes (as oppposed to components updating themselves by listening to events) Is there really a difference? Angular uses RxJS in a pub-sub scheme. (At least it did when I last used it.)
- dminik 7mo agoIt's much simpler. Reactive UIs and declarative UIs let you built things more more easily. You can almost entirely ignore an entire class of issues (state mismatch for instance). That of course led to developers building much more complex UIs. Which offset the gains from reactivity. Hence the mess and we're basically where we started.
- rglover 7mo agoYep. It's one of those great on paper, tough in reality models. Used sparingly and wisely, it can make great UX fairly trivial. But sadly, state is more often abused and loaded with tons of data and complexity it shouldn't be holding. Something, something just because you can, doesn't mean you should.
- speefers 7mo ago[dead]
- EGreg 7mo agoCounterpoint to SSR: https://qbix.com/blog/2020/01/02/the-case-for-building-client-first-web-apps/ https://qbix.com/blog/2020/01/02/the-case-for-building-clien... But yes, React is a mess. JSX was the original sin of mixing HTML inside JS. And those bundlers and tree-shaking at build time? Ugh. What if you had this instead: https://community.qbix.com/t/loading-at-runtime-the-web-framework-everyone-wanted-all-along/779 https://community.qbix.com/t/loading-at-runtime-the-web-fram...
- pfraze 7mo agoReactivity isn’t the problem. Reactivity is one of the few things that helps reduce the complexity of state management. GUI state is just a complex thing. Frontend development doesn’t get enough cred for how deeply difficult it is.
- pier25 7mo ago> I'm starting to wonder whether reactivity (not React specifically) was the originally sin that led to modern UI complexity I've always maintained that no reactivity is a much simpler mental model. Mithril and Imba do this with better than good enough performance. I think Remix 3 will be following this approach too.
- olivermuty 7mo agoIs this a satire thing or will it really be remix3? Didnt they just rebrand to react router FROM remix??
- pier25 7mo agoNo, I'm serious. The previous Remix was rebranded into React Router. Remix 3 will not use React and will apparently not use reactivity either. https://remix.run/ https://remix.run/ There was a presentation last year: https://www.youtube.com/watch?v=iZl0IKj0HHc https://www.youtube.com/watch?v=iZl0IKj0HHc
- olivermuty 7mo agoI’ll be darned. Too bad it will become abandonware most likely given the authors history lol
- bikeshaving 7mo agoI’ve written about how Svelte, Vue, and Solid are all reactive and share common pitfalls due to their reactive solutions. My theory is that they all cause worse bugs than they prevent. https://crank.js.org/blog/why-be-reactive/ https://crank.js.org/blog/why-be-reactive/
- codethief 7mo agoCompared to what? I mean, what's the alternative for an interactive app?
- bikeshaving 7mo agoManual refresh(). This is something Crank does, and other frameworks like the new Remix one is picking it up as well. Being explicit has its advantages.
- ndyg 7mo agoThe original sin wasn't reactivity. It was putting state in the wrong place. Making the client state heavy. It's been downhill since then. Now you need to duplicate state handling between your frontend language and your backend language. Which leads to "isomorphic" backends seeming like a good idea.