I’m currently exploring strategies to optimize data storage and retrieval for an enterprise-level application that demands high scalability and performance. In my quest to enhance efficiency, I’ve considered leveraging React’s capabilities such as memoization
, PureComponent
, and React.memo
.
One approach I’m contemplating involves storing application data within DOM elements and accessing it via a ref. Here’s a snippet showcasing my approach:
<div
ref={myRef}
data-my-data={myData}
>
<MyReactComponents />
</div>
I’m interested to know if this methodology aligns with best practices for achieving performance, maintainability, and scalability in React applications. Specifically, I’m seeking insights into the following:
- Will storing data in DOM elements as demonstrated above improve efficiency?
- What potential challenges might arise in terms of scaling and maintainability?
- Are there alternative strategies or optimizations I should consider for achieving optimal performance in an enterprise context?
Any guidance or recommendations from experienced React developers would be greatly appreciated. Thank you!
2
Answers
I don’t see how this would help. If you have data which is needed for rendering, it must be put in state, one way or another. That’s because state is the only way react knows it needs to rerender. For the uncommon cases where data is not needed for rendering than you can put it anywhere you like (including a
data-
attribute), but it’s also unlikely to affect performance.Most react performance issues come down to rendering more times than needed, or more elements than needed. In terms of general tips, i would recommend you keep your components small, and keep your states close to where they are used. Combined with the memoization tools you mentioned, these can minimize the number of elements that need to rerender when state changes.
If a state variable is needed by large portions of the app (a global state), then the standard react approach is to lift it up to the top of the component tree and pass it down. If you’re passing it down via props, this can force the entire component tree to rerender. So it’s often better to pass it down via context, and put a memoized component right under the context provider which can block rendering of most of the component tree.
Global state manager libraries can be another tool, because they are usually written to make good use of state under the hood. Eg, in redux, the
useSelector
hook is used to subscribe to the store. If the relevant part of the store changes, it will then set state in the specific component that calleduseSelector
, so the state is as close to where it’s being used as possible. Thus only that component and its descendants must rerender.And one final tip: if you’re putting a lot of things on the page but most of it is off screen, consider creating a virtualized list such as with react-window. This can have dramatic performance improvements if you are displaying a large list.
Frame challenge: Performance Is NOT a goal
If you’re asking in the abstract as an academic exercise, sure fine whatever, but you explicitly structured this as being about an enterprise app. Performance is not a business goal. Increasing revenue and reducing costs are business goals. Performance is useful if and only if it furthers those goals, and only to the degree it furthers those goals. As for that, well…
I’m the frontend architect for a large e-commerce React app that does about 10 billion USD per year in revenue. The short answer is that there isn’t a short answer. At that scale the only answer is "test everything", no generic internet advice is going to really help you.
Now sure, in our case there is a measurable correlation between e.g. Google core web vitals metrics and income. But you can’t just assume
Moar Performance === Moar $$$
, for instance in terms of pure conversion rates for us CSR beats SSR (counterintuitively) by about 200 basis points. Should you forget about SSR then? Not unless your customer base is exactly like ours! And even for our customers there’s a significant subset that are better served by SSR. Don’t assume, measure measure measure!If you aren’t set up to track those kind of metrics then forget about JS micro-optimizations and go do that first. If you are already set up to track those metrics, then why are you asking us?