-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: batch Subscription
listener notifications
#1511
Comments
As I mentioned in the other issue, we do already use batching within the individual react-redux/src/utils/Subscription.js Lines 23 to 30 in 77a2044
What you're describing is a different sort of behavior: trying to batch across multiple dispatches. That falls into how the Redux store notifies subscribers, which is a related but different topic. I just wrote a blog post on the various techniques that can be used for batching: A Comparison of Redux Batching Techniques When a given action is dispatched, React-Redux has no way of knowing whether more actions might get dispatched in the near future. All it knows is that an action has been dispatched, the store has (presumably) been updated, and that components need to re-run What you're getting at is effectively some form of debouncing or throttling applied to subscriber notifications, which can be done, but only by modifying the behavior of the store itself. The downside there is that this affects all store subscribers. In React-Redux v7, only the react-redux/src/components/Provider.js Lines 7 to 14 in 77a2044
However, any other subscribers (such as a plain Also see the Redux FAQ entry on "how can I reduce the number of store update events?" as well. Note that React's "Concurrent Mode" does actually batch queued renders across event ticks. However, given how the Redux store works, there's a whole lot of uncertainty about how Redux and React-Redux will actually end up behaving in a React CM scenario. See #1351 for the latest discussion on that topic. |
Yeah, this is just not how Redux works. We already do batching from the React side of the things, but the store itself will synchronously fire listeners when dispatching. There's nothing to batch without a store enhancer, which is out of scope for this project. |
Thanks for your detailed replies—it's really appreciated. Learning a lot here!
Couldn't React Redux debounce its own store listener?
I tried making this change locally and it seemed to work. Selectors are only re-evaluated once after all BeforeAfter |
That's not the default behavior we want, though. It may be something you might want, in rare specific cases, but as a default we need to re-render as quickly as possible. |
Given debouncing improves performance (as per above), what are the reasons why you might not want to do this? I'm speaking about debouncing the listener notifications only inside of React Redux, not for other store listeners. |
Exactly the reason I just described. If we start debouncing updates, the UI updates will be delayed. I'm certainly interested in potential ways to improve our existing behavior, but as far as I can see, you're focusing on the wrong metrics and constraints here. |
Just to check I follow what you're saying, are you alluding to the discussion we're having in the other issue, i.e. the need to use |
The latter. Debouncing might make multiple sequential dispatches result in a single collectively faster re-render than handling them individually, but it would make all individual dispatches render slower overall, and that's not something we want. If you'd like to put together some sample projects that demonstrate differences, I can take a look. You might also want to look at the React-Redux benchmarks repo at https://github.com/reduxjs/react-redux-benchmarks . But, simply off the top of my head, debouncing is not the approach we should be using here. |
Interesting, I thought that debouncing (with no wait time) wouldn't add any delay, in the same way that in |
Whilst investigating some performance issues on Unsplash, I discovered that when dispatching multiple actions in a row, React Redux will re-evaluate all selectors once each time an action is dispatched. It would be better for performance if it only re-evaluated selectors once after all actions had been dispatched, especially in an app with lots of selectors. I explain the problem in more detail here: https://medium.com/unsplash/react-redux-performance-considerations-when-dispatching-multiple-actions-5162047bf8a6#6af5
I understand that the
batch
function provided by React Redux is just an alias for React's own batch function. However, I wonder if React Redux could extend thebatch
function to avoid the problem I mentioned above.My thinking is that
Subscription
listeners would only be notified after all actions have been dispatched (i.e. when thebatch
callback completes), rather than once after each dispatched action—just like howbatch
works to prevent multiple React re-renders, it could also work to prevent multiple re-evaluations of selectors. This way, selectors are only re-evaluated once, and it wouldn't be necessary for users to do something like I did withredux-batched-subscribe
, as long as thebatch
function is used.Perhaps there has been some prior discussion on this subject matter, but from a quick search I couldn't seem to find any. My idea might be flawed but I'm curious to know if there is any other way we can provide a solution to this problem out of the box.
The text was updated successfully, but these errors were encountered: