I would say they all can be fast. But try browsing the web on a low end Android device and tell me all sites are fast. To my mind the differentiator is how easy a framework makes it to shoot yourself in the foot. And React makes it very easy to re-render a huge swathe of your app when you've only changed one tiny element. React also needs to hydrate every element even when it isn't ever going to change, which usually involves parsing some JSON payload for props on page load.
None of this is world-ending stuff. But it is very easy to keep putting wonderful, carefully crafted components together and not realise the entirety of what you've made is getting slower and slower over time.
That is no longer true with Server Components https://beta.nextjs.org/docs/rendering/server-and-client-com...
Don't get me wrong I'm glad the React team is tackling the problem but it's telling that the answer requires an entire server side solution when other JS frameworks are able to solve this in the client or at build time. And just looking at those docs screams "patching over a fundamental issue" to me.
It is not unusual at all to find some "simple" UI update causes the render() method to be called 20 times.
You might blame the application developer for this but other than "keep all the state at the top level of the application and pass it down in props", React doesn't provide a systematic answer for handling state in apps if data is flowing up, down and sideways. There are a number of half-baked libraries such as Redux, MobX that maybe help some of the time but frequently make very simple application logic very complicated to write. When I started writing high-complexity SPAs circa 2005 or so I realized right away that you had to be very systematic about what happened when an AJAX call returned and where the data goes, something the industry still hasn't entirely learned.
It is possible to make React applications work right but I think people work harder at it than they have to and there is a lot of reciting shibboleths that people don't understand (hooks for one thing) and the cost of it is the render function getting called over and over and over again. But maybe it is not a bug but a feature for the advertising supported web where every rerender and layout shift creates a chance you'll accidentally click on an an ad when you are trying to click on something else. Most studies seem to show that psychologically normal people of normal intelligence in possession of their faculties never choose to click on ads and maybe Google's whole business is driven by accidental clicks caused by layout shifts and doing something about those layout shifts would put them out of business.
The built-in React way of doing that is with context.
That's fine if you aren't writing any unit tests or trying to fix bugs with the debugger. If context are in use you might have some 'simple' system with 10 components that shows 150 components in the React component viewer most of which are worthless context blocks that are just there to waste your attention and probably the CPU and memory of your computer. Does Micron pay Facebook a commission for all the RAM this sells? Maybe people who are trying to keep their code obfuscated think it is a big win.
I am glad that the React team has painted themselves into a corner and they can't seem to successfully land new malfeatures like context, hooks, etc. It seems like they are re-arraigning the deck chairs on the Titanic repeatedly to prepare for the threaded rendering changes that they (hopefully) won't be able to deliver so at least the React development experience is not going to degrade quickly.
So let's first back up and recognize that this earlier statement was flat out wrong. React does provide a systematic answer for this.
Second, not only does it have a systematic answer, but it memoizes quite well because React will not re-render children if the `children` prop is identical to the previous render, even if you don't use `memo()`. This means it is quite cheap to have context providers update, even if you nest 2 or 3 of them.
The big issue with React in my experience is just that developers are lazy af and will stubbornly refuse to read even the tersest of docs even if they are encountering a new paradigm, like declarative and reactive UI. The result is a giant spaghetti mess of their own creation, which they then blame the framework for.
You can make React fast and you can keep it clean, all you have to do is topologically sort your data by the frequency of how quickly it changes. That's it. That's the trick.
For example recently I wanted to use a promises in React app. I mean: promises are as native to JS as it gets. Surely React should have first-class support for promises.
Nope.
So I started to write custom hook. usePromise. Like useEffect, but for promises.
Well, it would not be hard. But apparently React likes to call useEffect twice for dev mode. So I need to have a reliable cancellation. How do we cancel stuff in web? With AbortController, right. Does React heard about AbortController? Nope. So I need to integrate AbortSignal within my usePromise hook. I read famous Dan Abramov article, I read other articles, I spent days tinkering around this thing, I wrote several implementations.
All of those implementations are faulty.
Here's my latest one: https://pastebin.com/WBctCBpc. Technically it works. But it contains unpure reducer function. It's not broken in current React version. But who knows how react dev mode will torture my reducer in the next version.
I have to admit that I enjoyed toying with this stuff. But it definitely counter-productive to business values.
Now I know that this is all solved and I should just use react-query or something similar. Well, I have my reasons to avoid it. But my point still holds: React is hard, React is not well integrated with JS and Web. And probably React will get better in the future. I've heard about suspension stuff which might just be what I need, but it's not there yet.
Basically it should remove any boilerplate from user of this API and handle edge cases.
function Item({id}) {
const r = usePromise(async (signal) => {
const resp = await fetch(`/item/${id}`, {signal});
return await resp.json();
}, [id]);
if (r.status == "pending") {
return <div>Loading</div>;
}
if (r.status == "rejected") {
return <div>Error: {r.reason}</div>;
}
return <div>{r.value}</div>;
}
It's really like useEffect but provides better support for cancellation and properly tracks promise. Rewriting this snippet with useEffect correctly would require quite a lot of code (although rewriting this snippet with useEffect incorrectly is possible with not a lot of code, but you don't want to write incorrect code). Which has to be repeated everywhere.Again, this task is better solved by react-query or its alternatives. What I'm writing is not strictly web-site, but rather a web-interface on embedded device and web-server is not remote web-server but thing that works on the same device, so for now I decided not to use those libraries which made for slightly different use-cases.
If you're using just React, use React Query or something like `react-async`.
If you're using Redux, use the "RTK Query" data fetching and caching API in our official Redux Toolkit package:
It’s not quite directly using a promise but I was surprised I can’t use an async function in useEffect. It’s pretty common to perform async operations there, after all.
If you are building the average mobile app it is often really clear when you are writing code what needs to be updated in the UI when a piece comes in.
If you are building something more like Adobe Photoshop or Eclipse the user has the ability to open up property sheets and create other UI elements that could be affected by data structures anywhere in the application. In that case you need some systematic answer such as components registering to get notifications when something happens but you can run into some pretty bad problems such as having to hang on to references which keep the garbage collector from working as expected. My first SPA was a knowledge graph editor in GWT that I managed to get correct (though it probably leaked memory a little) and since then I haven't known whether to laugh or cry about the state of SPA frameworks.
As for the manuals I think the React manuals are some of the worst in the business. I have no problems finding answers in the Java manual or the Python manual or the Postgres manual or many others but the React manual baffles me.
Context was never a systematic answer. Even today the docs say:
Apply it sparingly because it makes component reuse more difficult.
If you only want to avoid passing some props through many levels, component composition is often a simpler solution than context.
https://reactjs.org/docs/context.html#before-you-use-contextAnd IIRC older docs would be even more harsh at recommending not to use context.
I agree. In fact this goes beyond frontend frameworks. One should apply the same approach to all methodologies and practices: OKRs, TDD, Agile, etc.
When framework/methodology is being sold to you, people talk about all the wonderful properties it has. But what you should really be care about is how easy it is to misuse and what happens when it does get misused. Because, trust me, it will get misused.
One of the most important things about particular technology is whether it lands you in a Pit of Success: https://blog.codinghorror.com/falling-into-the-pit-of-succes...
Holy smokes, that's more like a straw kaiju than a strawman. Obviously slow sites exist. That has almost nothing to do with the inherent overhead of recently created JS frameworks.
we don't live in the same universe. even with powerful computers, browsing any friggin modern website is an exercice in pain and frustration, everything, literally every interaction is slow when you compare to the average desktop app
If we are going to say things like "React is fast" then it needs a further clarification - fast compared to what?
Are we comparing it to C, jQuery, Angular, Pure Javascript, or a Commedore 64? Because it doesn't make sense to say it is fast if there isn't something to compare it against.
(In reality, I suspect it is only really "fast" if you compare it with something slow).
It’s like thinking that a faster car or a bicycle could be faster in a city with bad traffic light logistics. All of Svelte, React, Vue, jQuery, DOM are equally visibly fast until you attach these 10 megabytes of /metrics-n-spyware/**/*.js.
https://www.reddit.com/r/bugs/comments/rj0u77/reddit_redesig...
Although I also think it is fault of react partially. React don't really have a proper guideline about how to not write page like this.
When you say "fast" - I assume you mean runtime speed, not time to market/developer speed? Because FTA (quoting Pete Hunt in regard to React itself):
> Just like you can drop into assembler with C and beat the C compiler, you can drop into raw DOM operations and DOM API calls and beat React if you wanted to
Even the React people acknowledge that just working with plain-old Javascript is going to beat React (or Svelte, or X, Y, Z) is going to perform better at run time, they're just offering to speed up the development cycle - always with the tradeoff of runtime performance.
And what about user with a low end Android machine? Not lagging the ui isn't helpful here. Because it still need seconds to render the whole thing.
JSX and VDOM were at one time necessary (or at least helpful), but Web Components and Tagged Template Literals can do everything React does, only better and with less overhead (in both the developer’s mind as well as the computer’s runtime). I say that as someone who learned and taught bootcamps with React, and has yet to dive too deeply into lit-html and LitElement.
There's a vanishingly small number of applications where it's really going to make a difference. Use what your work uses, or if personal project what you like. The more I use React and co. the more I feel like it's all the same thing.
Developers (and especially deadline-conscious managers) keep saying this, but their web sites keep slowing down my computer to a crawl. As a consumer, I really wish that development teams paid at least some attention to performance.