Hacker News new | past | comments | ask | show | jobs | submit login

There's nothing really fundamentally wrong with React that makes it a terrible idea that always results in poor performance. It's shoddy development practices that can make for a bad app that uses React. If you use React well though, it's not like React makes it particularly difficult to reach a good level of performance. I typically find that React makes it easier for me to make a well-performing app, but that's just me.



I don't think it's even React itself that's the root cause the performance problems, it's using the data store badly (Redux or Mobx or even the new ones like Zustand and Valtio) that either causes components to rerender too often or causes too many components to rerender.

Having been bitten by this a few times, I'm paying a lot more attention to how my team uses it in the React app we're building from scratch right now, keeping an eye of how it's used and looking for problems before they become noticeable. I am, for example, inverting one of the common practices which I found was a cause of these performance problems:

"Atomic Design" with React splits components into different types - Atom, Molecule, Organism, Section/Template, Page. Each type of component is mainly composed of the smaller ones. It's generally suggested that Atoms and Molecules should be functional style and reusable, so not connected to the data store at all. Instead, Organism and up are the ones that manipulate data and pass things down into Molecules and Atoms to render. The problem here is that any update that triggers an Organism to rerender will also rerender all the Atoms and Molecules in it, even the ones that don't actually need to update (in the class-based component days we had shouldComponentUpdate() to avoid this, nowadays we have useMemo()/React.memo - neither of which we used with any consistency because of the extra effort).

Instead, while we do have a company-wide library of Atom-like elements we're using, the Atoms and Molecules inside the app are "smart" - they take a prop or two for configuration, then use that in combination with the data store to handle the data manipulation directly. Organism-level components then don't do any data wrangling and are just laying out what Molecules go where. This means when manipulating a Molecule, only that Molecule and any others looking at the same data need to rerender. The Organism and other Molecules in the same Organism are completely unaffected, not even trying to rerender and no need for React.memo to prevent it.

(Aside, to avoid confusion in the current app I haven't introduced the Atom/Molecule/Organism naming convention, and am instead using more semantic app-specific names for organizing components)

We still have a ways to go but we've already implemented the specific part I expected to cause the most problems here, and so far it's been great, the latency is so low it doesn't feel like a React app in the way I've come to expect, and there's much less manual manipulation of the data in the components themselves.


> I don't think it's even React itself that's the root cause the performance problems, it's using the data store badly (Redux or Mobx or even the new ones like Zustand and Valtio) that either causes components to rerender too often or causes too many components to rerender.

Like I said, it's shoddy development practices. I've seen apps that use one of those mutable object libraries (not any of the ones you listed) and just pass the objects everywhere. Whole app re-render on any state update because of how all of the state is nested inside these mutable mega-variables held by the root of the component tree. I try to chip away at the innermost components and create little havens that use immutable state as they should, but it's going to take years to redo the whole app that way, especially since refactoring isn't a priority yet.

By the way, a cool trick if a component you're using does not use `React.memo` is to memoize the element, because if React sees the exact same (reference-equal) element as the last render, it will not re-render the corresponding component tree. (Element refers to the return type of JSX expressions.) Obviously, only do this if it actually doesn't need to re-render.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: