What are the conceptual differences between Zustand and Recoil performance
Asked Answered
B

1

22

I've been looking into Zustand and Recoil -- two state management libraries that are relatively new.

Recoil is heavily advertised as being "very performant" for React apps with deeply-nested structures. However, I don't see how (or how exactly) it can be superior to Zustand performance-wise (concurrent mode aside).

I could've gotten it wrong, but here's how I understood it from articles and talks: The main reason "why" Recoil is performant is that any updates you make only trigger the relevant components to re-render, without bothering any other components. Recoil allows for it by design and out of the box, whereas Context-based libraries have to pass every change through the whole tree, have those changes diff'ed/reconciled and then probably only re-render what has to be changed.

Now, Zustand does not use the Context API at all. So, I would assume that (concurrent mode aside), it would have comparable performance benefits as Recoil, where Zustand would only "touch" the relevant components without ever piping the changes through the whole component tree.

Please let me know if I'm off in my understanding. Are these two libraries comparable in performance (without concurrent mode)? Or is there some other inherent property of Recoil's paradigm with atoms which makes it theoretically superior in terms of performance?

Please note: I would like the answer NOT to be influenced by patterns and practices too much. I understand that sometimes the biggest benefit of a paradigm can be in the "sound patterns it enforces", but I'm interested not in what they enforce but in what they allow to do with comparable effort. For example, I understand that a flat, normalized state will allow for better performance in Zustand, and that Zustand does not necessarily "force you to do it in a proper/scalable way". But I wouldn't want the "optionality" of the right patterns to be a disadvantage.

Burck answered 13/7, 2021 at 1:11 Comment(1)
In my quick look at the Zustand code it appears to work much like react-redux in its connection to React. You provide a selector and it diffs the result against the current result, if they are different (reference comparison) it triggers an update. This appears to have the same issue as react-redux where if the state updates even if a component does not require a rerender it is still going to run the selector and do the diff to check if it needs to update. You can see this here. I did not look at Recoil.Tachylyte
S
3

They both have their own pros and cons, that said you should base it on your project requirements. For example:

Using React's internal Context API, Recoil internally uses this API to propagate state updates to the subscribed Components, however, Zustand uses React's custom hook-based approach to handle Component state distribution. So even though Recoil optimizes Components within the boundaries of the Context you still going to have some performance overhead.

Zustand aims to do its best to reduce the amount of overhead associated with React's reconciliation process so we can rest assured that our UI will maintain synchronization with the application state while minimizing unnecessary re-renders and optimizing performance.

If you have quite a complex application tree of deeply-nested components Recoil's uses atoms and selectors pattern making it possible for you to define fine-grained Component dependencies, so when a specific atom change, only the Components that depend on that atom are re-rendered. That said, if your objective is to optimize the re-rending of Components, you should definitely consider Recoil as a solution.

Depending on how you want to manipulate the flow of your data i.e. reads/writes. If you looking for a unidirectional data flow similar to Redux, you should consider Recoil.

If you prefer a more direct approach with Zustand your state is stored in a single store and is accessed and modified directly by your components.

Shrive answered 26/5, 2023 at 21:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.