React 19 almost made the internet slower
blog.codeminer42.com
blog.codeminer42.com
Their rational was pretty solid in the PR, but seems they overestimated how ready the community is to embrace newer best practices and they are back tracking.
What are they, in plain terms? Is it just manually hoisting what you know a route needs all the way to the top of the tree? Or is it some compile time magic that analyzes your components used, making the decision for you on what to fetch for a route?
And Meta's way of doing this is with Relay, so you are still defining component data requirements with the components and query fragments, but there's a compile step that produces those route level queries.. so you still get "co-location of a component's data requirements with the component", and "top level early data fetch" for the render-as-you-fetch pattern.
This change breaks the fetch-as-you-render pattern where components make individual data requests for their data, because that pattern is considered bad for performance (for Meta's use case).
Essentially data fetching starts as soon as possible. Right after routing, right before rendering.
The fact that the suspense change made it this far shows how the react team has lost focus. Now more than ever, the ecosystem is really primed for a competing framework to dethrone react. I say this as someone that has invested a lot into using react.
Preact is how I wish React would have evolved: stay small, keep a simple interface, focused on being a view library instead of a sprawling framework.
Kind of discredits all your opinions on that topic
- React (if you want the largest support, packages, community, but sacrifice on performance) - SolidJS [1] (best performance, composability, low-level primitives, but sacrifice on packages/community)
Every other choice like Angular, Vue, Svelte are just somewhere in between these 2 spectrums which I felt was not worth it. Either choose the one with the largest ecosystem or one which has the best primitives & performance.
- React (vdom, slow) (largest ecosystem) - Vue (vdom, faster than react) (large community) - Svelte (fine-grain, faster) (best dx pre-v5) (composability is still not as flexible in v5 compared to SolidJS) (small ecosystem) - SolidJS (fine-grain, fastest, most consistent) (dx similar to react) (small ecosystem)
That said, framework choice isn't the problem, frontend devs having no clue how to design and use API's is.
I remember plenty of multi page applications from big corp that ran like a dead dog too, back in the day. Or ASP sites that wrapped the ENTIRE page in a form, with all of the frustrating complications that entailed.
I switched to straight HTML, JS + .ASHX handlers for a lot of things leading up to that point.
I'm not sure this is really the first thing that needs to be optimized for most people though, despite there being a lot of frameworks whose sole reason for existence seems to be fixing this aspect of react's performance.
There is no framework that has a "pit of success" that makes it inherently easy to build a fast app, so any team that uses a framework poorly is just as likely to use a different framework poorly. If they switch and things improve it's probably because the new framework happens to fit their mental model rather than any inherent function of the framework itself.
A good team that designs their code to make the most of a framework could write a good, fast app using any particular tech.
There's no framework that has a "pit of success" on every subjective performance quality metric, but I do think some frameworks more than others have larger "pits of failure" that make it too easy to get bad performance even doing what you think is supposed to be the right thing. Because I've vocally picked on it many times at this point, an easy example to mind is Angular's Zone.js is a big opaque library that can accidentally drop you into a "pit of failure" without you realizing how you got there. I'm glad a couple years after I raised some warning flags about Zone.js that Angular is finally addressing that elephant in the room and removing Zone.js as the suggested option and are close to removing it as the default option.
(I'm less glad that the reason that finally pushed them to do that is adding Signals. It seems wild to me to have proper Observables and also Signals and that just seems like another potential pit full of accidentally doing the wrong thing because it looks easy but the interactions between imperative code, Signals, and Observables is going to necessarily be complex and fraught with scheduling problems. I can't say that I'm surprised that Angular development is again moving one step forward while also two steps back at the same time.)
I know others with similar rants about React Hooks and how easy it is to miss needed dependencies in the dependency list of a Hook and too easily fall into a pit of failure.
It is useful to evaluate frameworks with some small eye to "how hard does this make it to do performance right if we follow its 'best practices', even in the case of simple mistakes?"
Essentially a lot of the tools we use are only meant to be view layers, and we constantly cobble together supporting layers (models and controllers for example) ad-hoc. Angular handles that off the shelf. I suspect a lot of people are put off by this because it feels imposing and they might not realize they're implementing the same stuff manually, and likely doing it worse.
I used to think it's plain old garbage but realized that's ridiculous. There are reasons people prefer it in some scenarios.
SolidJS is my favourite by a long shot, but I find myself using React because I know so many people I write for and work with are more comfortable with it. I'd be glad to use it more often if it made sense.
I think where it shines though is that it's completely batteries included, which I can see being useful for large enterprises where it's near impossible to change things.
Having recently worked on a very legacy React app, it became apparent to me the value of frameworks like Angular. If you can maintain it and upgrade it gradually, React is arguably the better choice. But if you're leaving it to stagnate, Angular is a far better proposition.
They think they don't need batteries included because it's 'bloat' or the opinionated patterns are inferior, but after a couple years they've got a couple dozen seriously bad patterns and a 400kb application that could easily be pared down to 100 or so.
This isn't so much a virtue of Angular or React specifically, but a reality of the deficiencies in our industry when it comes to the human side of the equation. These people would be better off following Angular's general conventions whether they realize it or not.
Not a great example since that’s actually why all the other propositioned system language replacements never took off in the way rust did. Rust is (or can be, but importantly, when used idiomatically and not just “in some form”) as fast as C.
There were lots of other languages that tried to replace C with better DX but failed because they weren’t Pareto optimal. So I kind of get GP’s point: DX alone won’t cut it.
Could you expand on this? SolidJS DX seems pretty great.
Did something bad happen to dx in svelte in v5?
There's new syntax for props, reactivity and state that's slightly more complicated for hello world applications but you really notice the differences for even mildly complicated components.
export let foo;
vs
const {foo} = $props()
looks far worse until your doing something like extending an input and you no longer have to deal with $$RestProps ugliness
type Props = {foo: number} & HTMLInputAttributes
const {foo, ...rest} : Props = $props()
<input {...rest} />
React absolutely fails in that regard. I try not to be a conspiracy theorist but I think React actively avoids web component compatibility as a form of vendor lock in.
(Though two years ago I think sveltekit — the app framework for svelte, without which svelte is incomplete for many cases — may not have been quite ready for production, so it was probably fair at the time.)
Define performance. Comparing render cycles is pointless. A better measure would be Google's web vitals, if you care about user experience.
Have a proper backend doing all the backend stuff and just render page components as if they where just the views of the framework.
All this server components nonsense is solving a problem that maybe Facebook has but almost no one else does. But people think they do, so a lot of complexity is added for no real reason.
Now granted, this is pretty much a given for any architecture (nothing is perfect): so maybe my expectations of what things should be needs to be reeled in a bit.
Disagree with that. Most UI frameworks, including ASP.NET Core, JSP and JSF (Java based frameworks), Ruby on Rails, and Django (Python) are all based on MVC. That's no accident. MVC works very well.
It's been a mess. Maybe I've just had bad luck seeing these architectures in action?
React wasn't designed to fit in the MVC model. However, if we are trying to draw an analogy, as far as I can see it most closely resembles the controller. It is where the events are handled to update the "model" (state), which are propagated to the "view" (DOM element). What makes you say V?
Source: https://github.com/facebook/react/tree/015833e5942ce55cf31ae...
React is good at V, it is not good at M or C.
How so? Under MVC, V is the visual representation of the model. React does not exist there at all. It relies on the DOM and associated technologies to provide that.
React does give a mechanism to keep the visual representation in sync with the data and it provides a place to handle events that update the data. While it is not designed for the MVC model, so we cannot truly speak to it in MVC terms, the closest analog to those seem to be the M and C.
I'm assuming you had to go back to a commit from 8 years ago because all future commits realized that whoever wrote that React is the V in MVC was confused?
Disagree. That's where React exists. Whether you specify V using turtle graphics style API, or DOM style markup, it is all still V.
function Hello() {
return <div>Hello</div>
}
The div object is where the visual representation is handled. React in this case is only concerned with passing data to it, which is explicitly the model's concern under MVC. Although I suggest that event handling is really why people choose React, and that is the controller's concern according to MVC.Again, React isn't designed for the MVC model, so we have to really stretch ourselves to find any kind of similarities. But if React was only the V to the greatest extent that we can pervert the meaning of V, what value does it add?
Efficient updates.
I think something other people sometimes talk about are single-page applications, in which case it's not a single component being rendered but an entire application. At that point MVC was simply disregarded by the developers because React is really just trying to be the V in MVC.
https://github.com/williamcotton/williamcotton.com/blob/3719...
That’s a link to a route handler (controller) that makes a graphql call (model) and then explicitly updates the DOM with renderComponent (view).
FWIW, that code runs both client-side and server-side and it is written in F# that compiles to both environments.
See, we're already not talking about MVC. Under MVC, the model updates the view. But, as you say, in your code the "controller" does the updating. Maybe you could argue that React is serving the role of the model here by actually being the place where the DOM gets updated, but, ultimately, we're always going to struggle with finding such analogies when React isn't designed for the MVC model.
Nope. Under MVC, models knows nothing about view.
Which is essentially one major part of what React tries to offer. Granted, in an ugly way as it has to deal with the harsh limitations of Javascript instead of having the power of Smalltalk to work with, but such is life.
And I think life is better without the V-C distinction. Models ofc still exist but the field has gotten more fine grained for the term to still cary meaning
So much this. As we built more sophisticated apps using React we were constantly frustrated with how much code was ending up in the views, and how difficult controller frameworks were to work with (looking at you Redux). So we built our own mini-framework that explicitly separates the view from the controller. Seems like a simply change but it is amazing how much more productive it makes developers, especially with large complex applications that need refactoring as they evolve.
Unfortunately our skills are in writing code, not marketing, so we don't have a fancy website like most frameworks. But the details are here: https://github.com/aha-app/mvc
Certainly redux isn't a controller.
This comment worries me because I was under the impression that RSCs are an option for a specific use case and not the one approach to rule them all. SPAs should be supported and expanded because they do serve a valuable purpose not only based on their use cases but also for developers. React being SPA friendly means people can spin up hobby projects, small applications and big non SEO reliant apps with ease. Going all in with RSC and ditching SPAs means that many will be discouraged from entering the react scene due to the sheer amount for things that used to be optional and now suddenly just became mandatory.
I liked react and I still like it. But I believe it’s on a path to alienate its user base.
I once created a HTML file with just a start/end HTML tag and 50k (unstyled) button elements in between, curious to see how it performs. I tried the same in Flutter on a release build (using Material widgets so they are styled) and the HTML was much faster.
I was able to tab through (changing focus by holding tab) the buttons in both Chrome and Firefox at a consistent frame rate with no signs of any lag, while FLutter struggled and lagged quite a bit with the same.
Would anyone know why that is? Are web browsers hyper-optimised for static documents (beating a "native" GUI toolkit for static documents)? Is Flutter just comparatively slow compared to Qt, GTK and so on? Does the styling have that much of an impact on performance?
I am aware that updating DOM elements is uniquely slow for browsers but this experiment was a surprise for me and I'm curious for an explanation.
Edit: I was coding it up now, but my storage is full (having trouble copying text to my clipboard and unable to save files) so I don't think I will be able to deliver on what I intended. Sorry about that.
On the HTML side, I had a code generator (in Javascript) that output `<html> <button /> <15000 more buttons.../> </html>` and wrote it to a file.
On the Flutter side, I used the default Flutter sample app (`flutter create .`) and I just used a similar code generator to put 15000 buttons in a Column widget.
I don't think I'll be able to do much else to help with reproducibility sadly.
If others try the same, I would be interested in if their results are any better than mine (with Chrome/Firefox being faster).
Of course, it's unfair to allow Flutter to have optimizations but not the raw HTML, but disallowing well-known, real-world optimizations is also an unfair test IMO.
But, that's a very web-specific UI design idiom that you just don't find in typical native apps. If you change your test to use desktop UI as it's intended to be used, and then stick say a few tens of millions of buttons in it, then the browser will find it much harder and the desktop toolkit won't break a sweat.
Yes. The browser is the world's most widely deployed and used runtime. I would assume Blink, WebKit and Gecko are the three most carefully optimised pieces of software ever.
Don't assume usage patterns. Measure them, or you know nothing.
Github search for "import react", 56M results: https://github.com/search?q=%22import+react%22&type=code
Github search for "</Suspense>", 220k results: https://github.com/search?q=%22%3C%2FSuspense%3E%22&type=cod...
Thanks for the mildly condescending attempt to give me your earthly wisdom, though. Believe it or not, common sense can occasionally be just as useful as hard data. Maybe this can be a learning opportunity for you instead.
- You're looking at open source projects only (Most users of Suspense are going to be commercial closed source)
- You're looking at all versions of React over the last 12 years (Suspense is fairly recent)
- You're not weighing by number of stars, users, contributors, activity (E.g. you're probably 5M "React getting started" projects in there)
So, no. Still not. Anyway, by now the React team acknowledged that their initial decision was biased and decided to not ship React 19 without a solution, so we're good!
It works totally fine UNLESS you load something like a crazy landing page with animations. I always end up having to kill Firefox and prevent that site from opening.
One unexpected benefit of LLMs is they’re more performance friendly, I can query the docs of what I’m working on without loading the docs themselves.
If I had a team that had gone all in on Svelte I'd be bemoaning the need to upgrade recent code already.
I'm up for cheering for literally any alternative. Any.
Of course, I would rather quit than work within such a strict framework, but React going there halfway is even worse.
Are React release cycles that long? What's up with the title that it "almost" was slower if it was released? I assume I'm missing some context here.
[^1^]: grep "This happens because of the following PR:"
[^2^]: article publication date is June 17, 2024, tweet screenshots are dated between June 10th and that date
It's very straightforward, yet a complete surprise to me. I guess I'm just replying to invite someone else to give me a long-winded explanation of how the JS ecosystem works.
ex. now I'm flummoxed as to how Vercel/next.js exists/releases new features, if they're based on React. Seems you'd either get stuck living on React top of tree, unreleased, or have an unholy merge to do.
This is admittedly rare in the JS ecosystem.
They run on canary react releases. It's a not that hidden dirty "secret".
>"In React 19, we’re adding support for rendering document metadata tags in components natively:
function BlogPost({post}) {
return (
<article>
<h1>{post.title}</h1>
<title>{post.title}</title>
<meta name="author" content="Josh" />
<link rel="author" href="https://twitter.com/joshcstory/" />
<meta name="keywords" content={post.keywords} />
<p>Eee equals em-see-squared...</p>
</article>
);
}
When React 19 renders this component, it will see the <title> <link> and <meta> tags, and automatically hoist them to the <head> section of document."
This is one of the most brutally stupid things I've ever seen, and has pretty much sealed the deal on me dumping React at this point.How is this “brutally stupid”?
It does seem pretty weird to put it inline with the jsx. There's no indication it has a non-local effect on the DOM. Feels a bit magic for my taste.
Very little of what react does seems reasonable to me though.
Using JSX does. Especially for stuff like meta tags where there can be a couple in force at once.
I’m not going to argue it’s perfect but it seems like it fits in to me. It’s basically acting like the restrictions on where the title and meta tags can go no longer apply so you can just sprinkle them wherever they hopefully belong in your app. And react takes care of putting them in the right spot.
> Very little of what react does seems reasonable to me though.
So are you someone who dislikes it in general and just using this as one more argument?
I’d be very curious to see the opinion of someone who likes react who thinks this is a bad idea.
My general thought is that non-local changes should require some special annotation or something. For whatever that's worth.
I love(d) React to death from day one, and I've been using it every day professionally as a front end dev since 2016. This is precisely why the feature upset me so much. As another commenter said, they are clearly jumping the shark here. How exactly will this even work? Does this mean that every single render of every single component now has to tree shake the VDOM for <title> and <meta> tags? And now I'm encouraged to spread these things out all over my app instead of handling them centrally? Again, brutally stupid.
It completely breaks the React paradigm of a single mount point that handles DOM concerns, and introduces god knows what kind of global side effects. The beauty of a React component was that they could be treated as fully self contained little bits of UI. This is basically taking us back to jQuery.
That sounds 100% reasonable.
Someone noticed it, pointed out it was a big problem for them and enough others it got reverted.
That seems 100% reasonable too.
My controversial opinion is still the same, the less front-end you have in your stack, the easiest you'll be able to scale.
This is such a lazy, grandstandy, unoriginal take.
>My controversial opinion is still the same
It's not controversial it's just tired and ignorant.
Tired maybe but not ignorant since I helped to maintain two React SPAs for 6 years now so I'm pretty aware how bad it is.
Heavy use of interactivity is hard. React makes it maintainable. It was hell before.
I've been working with React (and RN) since it came out and I've had nothing but good experiences, especially compared to the previous decade before React.
My motto is local-first, the more stuff the client does, the cheaper it is to scale and less bridging between the server you have to do.
Move everything to the client, especially the database. Let the database do the syncing. Plus you get offline and undo/redo basically for free. Pagination? Fuggetaboutit.
My general complaint is the JS ecosystem in general and its tooling.
Agree, React is great for UI interactivity.
> ...the more stuff the client does, the cheaper it is to scale and less bridging between the server you have to do.
Disagree. The most costly form of scaling is people. UI + business-logic + data-modeling + data access (ACL) all held in async client concepts is a complexity nightmare in my experience. Even for my team-of-one side-projects.
Server <-> client bridge is a feature for managing complexity over time. I may agree that added ceremony could make 95% tile app experiences default harder. But for anything that's not a toy, the #1 risk is always team/people/communication complexity.
I'm in a company with around 100 devs now and I can certify you that front-end SPA do not scale at all unless you throw a insane amount of devs hours in the tooling, even then it barely does.
That's not mentioning the insane npm churn that you have to maintain, the testing story which is pretty abysmal outside of a few top libraries, the typescript tooling which is eating so much ram that I'm changing my laptop.
And I'm not sure why you mention the pagination as a plus where it's one of the big downsides of the front-end stack, there's a lot of hacks to make it behave okay in most situations.
What is the difference between SPAs and other monolithic architectures, e.g. on desktop, that makes it so? Why can’t you go with OSGI-style plugins, for example? Loose coupling, separate SDLC and deployments etc?
Native apps do not suffer from this problem, your binary can add an extra 20mb without much downsides
Browsers can handle many GBs of storage. You can even store them via OPFS directly on the native filesystem if supported. There's also Chrome File Storage API and if all else fails IndexedDB (which is more limited, but works decent for synced databases).
SPA assets (just like game assets) can be downloaded and cached on demand. They don't have to be bundled at all.
Native apps can do similar things with dynamically linked libraries, and there's a lot of complexity when it comes to compiling native code.
The web bundler tooling really isn't that complex nowadays, especially with Vite. It's one file usually 10 lines long. It can use SWC and LightningCSS, written in Rust. They're safe, fast, and require minimal config.
Then there's the complexity of the caching in continuous deployment, we literally have a custom metabase dashboard to make sure the caching isn't too bad and lasts a few days.
Then the default config doesn't scale either as you can guess and we have our own.
There's a reason I have this opinion, I know what I'm taking about, I've been using all those tools and they add a lot of complexity to your app.
The reason it works on an native app is because loading a dynamic library is essentially free, it's just stored alongside the binary.
We can agree to disagree though.
Our full bundle itself is close to 70mb and still growing every week, that's absolutely insane.
There's a reason why Vite has a default bundle chunk warning of 500kb.
There's really no reason it should be that large. If you just lazy load each route your chunks should distribute into manageable size pretty much automatically.
It sounds like you may also have a bunch of dependencies. Which can happen in a native app, but in a web app as you know you'll have limited resources so size is important.
This is the most popular opinion on HN. If anything, it's controversial to say React isn't a dumpster fire
Sadly, many products require sophisticated frontends, the FE is often a core part of the value proposition. React may be overkill in smaller cases, but it's a good tool in these cases of complex dynamic UIs.
For simple frontends that don't need to be complex UIs, I definitely don't turn to React (I love simple tried-and-true templating systems like ERB and/or EEX), but I definitely think React has it's place. Not everything should be SPA, but that doesn't mean nothing should.
also average HN commenter: If you use Python for your backend you're a moron, you need to use Rust so the API calls for your 0.5 requests/sec web app finish in 100ms instead of 125ms (note: 99ms is waiting for the database).
I’m one of them.
I'm agnostic because I quit full stack web development ~6 months ago. I think the product development story sucks and combined with the market economics of the current tech industry is just not fun or profitable to invest my career in.
It's -probably- a good thing that stuff like SSR becomes mainstream/required. But I really don't like that one of the main entities behind it, Vercel, has raised $563M as of their latest Series E as they steam towards an IPO of their Framework/Cloud offerings.
Can the web make the rest of the internet slower.
You have to click the timestamp on the comment first, then you're sent to a new page that only shows that one comment and a favorite button.
Sometimes the favorite button doesn't appear so you have to click the timestamp again.
Then we stopped sending html to insert into the DOM, and started sending JSON with a bunch of extra steps in between.
The fastest sites I see these days usually just reload the whole page pretty often.
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.
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.
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.
I wonder if some of it is a perception issue: Everyone, including the instruction manuals, Stack Overflow, and search results, are talking less and less about the way I do things, and more about these new ways.
You can also try changing it from the inside, but it’s swimming against the current.
If you’re a decent engineer, learning a new library should be the boring part. It’s not like any of these libraries are introducing highly specific conceptual paradigms.
The average developer doesn’t get to choose at all. This liberty was taken away from them in the name of “easier maintenance”, a “larger community”, “stability” (ha) and other ill-informed platitudes. This became a self-reinforcing cycle when companies started hiring for React experience.
The cycle continues. People acting like the [current popular thing] is the problem are missing the forest for the trees.
The latter got a lot worse. Along with React came the rise of evangelists, celebrities and their courses and a generation of developers raised on the idea that github stars are the ultimate measure of software quality. The jQuery era was peaceful by comparison!
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.
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.
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.
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.
but I admit something is off with react somehow (and i'm pretty favorable to it usually).
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.
But now it just feels so heavy and that the initial elegance has been lost to history entirely.
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.
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).
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.
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 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.
I learned more, and ended up writing my own react-like framework in Rust/WASM. (Seed).
Now, I program in HTML, CSS, and JS. If the project triggers a certain complexity threshold, I'll bring in TS.
React advertising itself as fast was a lie.
Yep. The tide is turning fast toward Vue these days. React died with the departure of Abramov. It's been over 2 years since the last major release, and 19 just screams nonsense "makework" incremental stuff.
Not saying you're wrong, as I have no evidence either way, but a more useful measure to see what's happening would be a plot of the numbers of React and Vue sites over time.
[maliker starts the bbq]
I feel like HTML had a lot of assumptions around desktop PC usage.
<style>
.image-container {
position: relative;
width: 100%;
height: 0;
padding-bottom: 80.44%; /* h/w aspect ratio */
background-image: url('https://d7hftxdivxxvm.cloudfront.net/?quality=80&resize_to=width&src=https%3A%2F%2Fartsy-media-uploads.s3.amazonaws.com%2F2RNK1P0BYVrSCZEy_Sd1Ew%252F3417757448_4a6bdf36ce_o.jpg&width=910');
background-size: cover;
background-position: center;
}
</style>
<div class="image-container">hi</div>
<div class="image-container">hi2</div>
<div class="image-container">hi3</div>
Though it seems laggier than the React version when I resize, and this doesn't get into making the text resize to fit the divs...What you have is basically just an image element with width: 100 height: auto, but it has children.
Here's an example, written with tailwind for my convenience but should be pretty legible to anyone who knows CSS:
<div class="grid place-items-center [&>*]:[grid-area:1/1]">
<img
src="https://picsum.photos/500/400?grayscale&blur=2"
class="w-full h-auto"
/>
<div>Hello.</div>
</div>
<div class="grid place-items-center [&>*]:[grid-area:1/1]">
<img
src="https://picsum.photos/500/400?grayscale&blur=2"
class="w-full h-auto"
/>
<div>Hello.</div>
</div>
<div class="grid place-items-center [&>*]:[grid-area:1/1]">
<img
src="https://picsum.photos/500/400?grayscale&blur=2"
class="w-full h-auto"
/>
<div>Hello.</div>
</div>
The height of the container is governed by the height of the image (until the text becomes taller than the image). You still have fully fleixible in terms placement (place-self) and/or sizing (height: 100%) of the text container.Then again my friend somehow got lured into installing Bootstrap.js, some React router, and frikin Redux to "solve" this before I told him no. But it's not like he understood what any of that did.
I'm dipping my toes in now for the first time since then, and I gotta say - I don't hate it as much as I thought I would. Yes, you can end up with library soup if you're not careful, but a lot of what used to be difficult is now quite easy. There's been genuine forward progress, and it's really nice to see.
(Though there does appear to be some kind of allergy in the web dev space to describing things intelligibly. It's never "XYZ is a stateless UI library built in TypeScript", it's always "XYZ lets you build bleeding-edge shardable solutions in the Web 3.7 space using YAML elem-nodes called 'qooms'. Let our bosomy anime mascot walk you through our getting started guide by simply piping this Discord link into a superuser shell")
IMO a lot of criticism aimed at frontend development is latent cPTSD from a bygone era but things have really come together over the last half decade. NextJS and friends are bloated, but that's nothing to the shit-show that was Webpack et al. Now that that's mostly over, next-gen tooling like Vite make the development process a lot easier.
CSS especially is a lot better than it was a decade ago.
This has all become too complicated as is traditional. Every JS framework I have ever used ultimately suffered the same fate. The only web framework that works long-term is whatever is documented on MDN.
Something approximating PHP + AJAX has always been the correct path. If you are doing things like shipping DOM across websockets, I think you may have missed an important step somewhere along the way.
The current style of web platform documentation tends to resemble a big list of objects, or the most basic and slowest introduction to web development possible.
Something in-between, with chapters like “templating” or “data fetching” that focused on some opinionated but framework less structure, would be nice.
I think there's easily enough API surface area to cover every part of a front-end web application without any dependencies.
Y'all are inventing your own problems to solve.
Not only have I seen multiple organizations lay off entire frontend groups, but as time goes on I work with more and more people who specialize in only this end of the stack and need people like me to wade in and solve actual problems for them.
Under the hood I know how things actually work and I can quickly get up to speed on their issues, whereas it's not always so easy going the other way.
Also if I had a dollar for every time I had to help web engineers "figure out" why the Sentry p95s are so high when sending large binary blobs on multiple round trips between Eastern US and Japan, I'd be a rich man.
If you don't want an interactive website, sure, just do everything on the server. That's a fine decision. Most of us work on apps where interactivity is a must
This is a false dichotomy. Gmail launched in 2004, React launched in 2013. Clearly interactive websites are possible without React.
As soon as you have the need for complex UI interfaces (anything beyond a multi-select box and modals) in the browser, which almost every serious SaaS app requires at some point, you're going to need complex JS components.
I still think its crazy to use React/Vue beyond very isolated components of functionality and 100% simple server side should be the default unless absolutely necessary. But that's why the frontend industry is already moving to 'islands' of complex JS that is SSR by default.
That said, there still seems to be a high burden of adoption of SSR "islands", where you have these complex frameworks like Rewind/Next that still assume React/Vue as the composition of server side views instead of just pieces of the page.
Which is probably why so many sites end up with a TON of JS views that are unneeded. Because frontend devs are in their own world/dev enviornment. We really need React/Vue SRR+hydration that blends well into Rails/Python/etc frameworks without needing to commit heavily.
Some UI gets this but often I find that most does not and that's the most common complaint that I hear from company to company..."you have the most advanced product but I need to take a two month course to figure out how to use it".
Customers really just want to buy your product, do nothing and get money and the closer you can get to delivering on that experience, the better.
You will always get more value from building APIs and integrations with other products than you will from putting options in the hands of users, but the big players in industry know this and build big moats intended to keep you out rather than improve everyone's products and their customers happiness. The problem is as workers in this industry we've taken the money and been good soldiers rather than demand and enforce open standards that would benefit our day-to-day and society at large.
I haven't even started in on the darker side of UI/UX like dark patterns and "engagement". It's not like "Sam's Pizza Shop" or any other small (or even medium) business needs some super complicated UI/UX and building that out for them would leave them worse off. Complicated JS frameworks should be the exclusive domain of companies employing hundreds+ of engineers and even then you have the problems from the last paragraph. IMO if you choose to work on frontend and perpetuate all this behavior, you're part of the problem.
Agreed, simplicity can be part of a great UX
> JS frameworks should be the exclusive domain of companies employing hundreds+ of engineers
Definitely not. All it takes is a few comboboxes, date/time pickers, or literally anything wanting client state, to deliver a FAR better UX using js than pure html. If you tried building the kind of experience expected by today's consumers without js, you would know. People have very little patience for mediocrity on the web
Simple tech does not mean simple UX
ADA lawsuits against websites are massively on the rise (I worked in the early stages of WCAG compliance and helping people seek to bring such lawsuits).
You don't need all that fancy shit to deliver something that works and every time you go overboard with it you're alienating someone...
Edit: Also, wth? Every browser supports showPicker() and you can control and style the crap out of that without pulling components and frameworks into the mix. Nobody's saying don't use JS at all here. You don't need teams of engineers, components and a whole frontend build toolchain to put forms on a basic website. THAT is the complaint here. Not "caveman think JavaScript bad".
It's complex UI requirements, not complex UIs...
For ex our company routes phone calls and needed routing system that had 3 layers deep of hierarchical organization, reordering, sorting, weighting, grouping etc.
You could have done all of those with a new page load every time, or spread out into individual static pages, but that'd take 10x longer for the user. I built something that did all of that in a box that fit into one screen and one page load, and only 1 ajax request for autocomplete search box.
Some things just demand 'desktop style' complex browser UIs that server side simply can't provide...
Which is why every serious company that makes $$ uses it. Backend devs like to pretend they can throw the baby out with the bath water and call it day, then deliver poor UX because they limit themselves artificially, just because some people abuse JS.
That's not the solution.
And then in three years when the undermaintained bit of software needs to be updated the entire landscape has changed in the JavaScript world 4x over already and the tooling needs to be entirely redone along with the desired change.
Again, nobody is saying "you don't need JavaScript". We're saying that the way you folks are going about it is Hell's Treadmill.
At least if I have a languishing, old, unrebuildable bit of code on the server side, I can find some exploit to make it run my code changes without modifying any of the original code :D
Every company I work at that uses G-Suite has me begging for Outlook even though I haven't worked with Windows professionally in over 15 years.
That's a big if.
(In case people see this tldr and actually start changing their apps)
[1] framework code: https://github.com/mickael-kerjean/filestash/tree/master/pub...
[2] example: https://github.com/mickael-kerjean/filestash/blob/master/pub...