Hacker News new | ask | show | jobs
by afavour 728 days ago
I remember when React first came out… it was actually a dream for performance initially. The VDOM diffing made complex, fast moving UIs way easier to run performantly.

I lost track of it around maybe version 0.6, by the time I picked it up again we were in Redux land and the framework was five layers of crap deep. Sigh.

5 comments

This is a friendly PSA that you don’t need to know or care about reducers, thunks, sagas, Redux, Flux, Next, React Native, React Native for Web, CRA, etc. in order to simply use React productively. Despite the humongous ecosystem with elaborate architectures and some slow or footgun-enabling implementations that’s grown on top of it, React itself is still a relatively small and lightweight library. A couple of lines is still pretty much all it takes to get from some pure HTML to working reactive rendering on the client. (I’d still do that on a new project—it’s a good opportunity to see what’s best from first principles today, as opposed to when you started a project last.)

The most radical addition since the early days are functional components and hooks, which are not mandatory to use (class-based components are considered “legacy”, but aren’t actually deprecated). Another one is RSC, and you need to care about those even less (though they can come in handy in some scenarios).

Okay, there was one more somewhat significant change under the hood: in 0.14 they’ve made React more of a general-purpose library, splitting DOM-related specifics into ReactDOM. This separation can’t come without some overhead, so it’s unlikely React would ever going to be the most performant for the Web. (Last time I looked, Preact was faster—they did abandon that layering and went with the coupled architecture.) However, that didn’t magically turn React into a slow bloated framework—but it did enable a variety of interesting non-Web applications such as rendering native apps, rendering on embedded LCDs, etc., where you can use React core as a standalone renderer with your own reconciler instead of ReactDOM.

To me, the initial allure of the vdom was how much further it got you then backbone.js’ “this.model.on(‘change’, this.render)”. When that one liner in backbone was enough, it was magical. But once you hit scenarios where overwriting the this.el.innerHtml, it became super painful (usually when that el was hooked up to 3rd party plug-ins, html5 video tags, etc).

Once react switched from class based components and mixins, each subsequent release was only more confusing. I remember the conference talk where they explained the problems with mixins (forgetting to cleanup and them all sharing one state), both of which can be solved in a few different ways, but they opted for a whole rewrite for hooks, which I “get”, but think it increased the complexity dramatically for a very low gain.

> The VDOM diffing made complex, fast moving UIs way easier to run performantly.

That was marketing more than reality.

VDOM diffing isn’t the slowest way to update complex UIs but it isn’t the fastest either. In practice your app often ends up generating a lot of VDOM which then gets diffed away… a bunch of work and then a bunch more work to determine the first bunch can be thrown away. The app developer needs to step in to manage and optimize the process.

Believe me, I know. We were manually diffing in a previous version before React came along and it was a shitshow.

The primary initial benefit with React was an improvement in reliability. Our previous implementation (in Backbone IIRC) wasn’t doing it quite right. Having it built into React was a gamechanger. Then with judicious use of shouldComponentUpdate you could minimize the amount of VDOM thrashing required.

I know at one point we explored immutable.js to make the diffing super efficient but the DX was pretty bad. I’m excited for JS to get records and tuples at some point and make that all way simpler. But for now it feels like shouldComponentUpdate and PureComponent are a lost art of React, few do it.

I’d love to see these narratives actually demonstrated in tests via blog posts. I suspect it’s more a demonstration of human memory and perception than it is of reality.
Well, you can go back and look at the original blog posts announcing React? I assume they're still on the internet somewhere. React was a pretty massive speedup over the portions of Facebook and Instagram's frontends that it replaced and they showed off their benchmarks a lot early on. That library had very little in common with the thing now known as React, though.
Frontend development is the most quickly revolving cycle of enshittification I know of.
Enshittification is when a company offers an amazing product, but once they have a hold over the market, they make it worse and squeeze customers. It works because customers are so locked in and there are market forces stopping them from switching to a competitor.

Frontend development is not being enshittified. We have so many frameworks that you can switch to if React isn't your cup of tea. Hell, you can use Astro and use React, Vue, Svlete, etc and it renders to HTML. HTMX is a new framework and easy to pivot too since React devs know JSX.

React is also silently borrowing ideas from Svelte and Solid.js (and those were inspired from React) so all these frameworks are improving each other without even knowing it.

This is what I don't really understand when people are airing their grievances. What exactly is the problem? You can absolutely write webpages and software the same way you could 5, 10, 20, etc. years ago. There's absolutely nothing stopping you from making a VanillaJS website or JQuery or whatever. Nothing went away. There's just more choices.
> There's absolutely nothing stopping you from making a VanillaJS website or JQuery or whatever.

There’s nothing stopping me doing that on a solo project but frontend web dev is increasingly a monoculture around React so when you’re talking about making this decision in the workplace you end up using React whether it’s the right idea or not.

I worked at a place that ended up using React because a senior manager was concerned about hiring and wanted to use something we’d be able to easily hire for. It wasn’t actually a good tech fit but that wasn’t the priority. And in many ways he wasn’t wrong. There’s a mini-generation of developers that have only experienced front end development though the lens of React and have barely if ever used, say, raw CSS.

Their grip is not with React per se, it's with the pressure to use new, updated features. Hooks was like this when they were introduced. People were so used to using lifecycle functions and then hooks became the "official" way. Users could still use classes and lifecycle functions, but since it was not the new "preferred" way, devs had the pressure to update old perfectly working code.

We're seeing the same with RSC. Many Next.js users are updating their apps to use the new App Router, but I've seen many just stick to the Pages Router since it just fucking works for their app and RSC has improvements, but none they care about.

Easy to say, but trying to avoid React will make it a lot harder to find a job. Any reasonably-sized company is neck-deep into React.

You can also try changing it from the inside, but it’s swimming against the current.

To me, enshittification also includes the feature bloat that comes from product managers and designers having to justify their salaries, which slowly turns things that were once lean and elegant into sluggish UI goop.

And that perfectly describes what is happening to frontend development.

> We have so many frameworks that you can switch to if React isn't your cup of tea.

Yes, that is what I was alluding to by calling it a "revolving cycle": Dominant Framework A is a bloated mess -> Framework B appears, it's lean and a joy to use -> Developers switch to Framework B, it becomes dominant -> Framework B gets enshittified into a bloated mess -> Framework C appears, it's lean and a joy to use

Happens everywhere in software, but in web frontend dev, it happens a lot more quickly.

What you’re talking about is true and worth pointing out. But it isn’t enshittification:

https://en.wikipedia.org/wiki/Enshittification

yeah early releases made intermediate stuff very lean and fast (as a user), more so than ad-hoc event based vanilla/jquery logic spread around (good luck tracking dependencies).

but I admit something is off with react somehow (and i'm pretty favorable to it usually).

Something seems off because marrying HTML, CSS, and JS is a complex abstraction and with trade-offs. Then you throw in SEO, so hydration gets created. Then JS can be used in the server too so you have to manage both states. Then, users don't want a blank screen, but a loading screen so they know the website is working.

Before you know it, you've created a whole new paradigm that has it's own sets of new problems, even those solved by the original HTML/CSS/JS model.

I loved React when it first came out. I never got into MVC frameworks like Backbone or Angular because they felt too heavy, but React came as a promise that it was only the View layer and that provided a lot cohesion, as you say, compared to too much jQuery.

But now it just feels so heavy and that the initial elegance has been lost to history entirely.

>something is off with react

The amount of rope it gave to hang yourself. Hooks were the harbinger of the sad state that what was to come.

The OG React was a breath of fresh air because it introduced the world to immutable data flow. The component model was dead simple. You had a fat (for better or worse) class that served as a management point for your side-effects and IO, then a bunch of stateless transformation functions / components.

The old class + lifecycle methods imposed a much needed friction on the development process. Their clunkiness was a feature (imo). It raised the cost of creating stateful components / performing side-effects wherever you wanted.

Then hooks showed up. In a lot of ways, it feels like React is now rediscovering the bad parts of OOP: uncontrolled mutation and side-effects. "Immutable data flow" means very little when everything is launching side-effects, updating some global store, modifying 12 layers of caches, writing to local storage, etc. etc. etc. etc.

It became a complete nightmare to reason about what an application was actually doing. Most of my experience with React (at least as of a year ago) was debugging performance issues, or UI quirks from component A clobbering updates from component B, because some special GraphQL caching magic modifies some global cache somewhere in some provider, which is 37 layers removed from the code you're actually looking at.

>It became a complete nightmare to reason about what an application was actually doing.

And anyone with any kind of software experience knew this was going to happen when hooks were announced. But the community bought it wholesale and dove in head first, so the rest of us were dragged begrudgingly along. I think it's been long enough now to resolutely say it was a bad idea and should have never been pushed the way it was.

The last paragraph hits close because I've experienced a similar issue recently. It turns out some component library was responsible for excessive rerenders even when idle (eating up the daily quota of read operations on some database for a small project).

As a stopgap, I just made a completely unstyled alternative to that internal admin dashboard that uses Handlebars HTML templating (no Javascript) on the server. Inclined me towards dependency rejection (which is an approach I was already taking for some side projects).

Would you have any recommendations for someone looking at learning vdom frameworks today?