Performance downgrade after update to v.6.0.0
See original GitHub issueDo you want to request a feature or report a bug?
Bug
What is the current behavior?
In ver.6.0.0 current state passing into context provider, it leads to update on every consumer (every connected component (on context.consumers)). Wrapped component isn’t updates but React has work to be done and its influence on performance is greatly negative. Our case when there is connected input to store and there are a lot of connected components on page and user starts typing fast (like long keypress), in this case we see lags (like input freezes and throws updates by portions).
What is the expected behavior?
As it was in v5.1.1.
Which versions of React, ReactDOM/React Native, Redux, and React Redux are you using? Which browser and OS are affected by this issue? Did this work in previous versions of React Redux?
"react-dom": "16.7.0",
"react-redux": "6.0.0",
"redux": "4.0.1",
As an example, you can check this fiddle https://x3yqx3ov1q.codesandbox.io/ - (upper component with greetings mustn’t be updated when new ToDoItem added) Source code of fiddle https://codesandbox.io/s/x3yqx3ov1q
UPD it can be related to this issue in react repo https://github.com/facebook/react/issues/13739 If so, what is the workaround (only one we came up with - downgrade of react-redux to v5.1.1)?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:6
- Comments:35 (20 by maintainers)
Top GitHub Comments
@markerikson @Jessidhia here is a code sample https://github.com/PashaPash/connect-sample Sorry for a lot of garbage/unused code, copypaste from the typescript prod until I got some minimal working example. Most of reducers and components are unrelated, can minimize it to some clear code if needed, but that will take a while.
Here what on the page:
Measured timings on dev machine, i7-7700k,
On 5.1.1: Only text box gets updated. Total event time: ~6-5ms: Interactive update (<1ms Tree Reconciliation + Changes commit): ~1.5ms,
Timeline:
On 6.0.0: All connected rows gets updated (but not re-rendered) Total event time: ~15-16ms: Interactive update (10ms Tree Reconciliation + Changes commit): ~11ms
Timeline:
There is 6x slow down for the interactive update part. 10ms difference may not be an issue, please note that I’m measuring on dev pc, and components tree is quite simple. Things are getting worth on average client PC. Typical consumer Core i3 is 4x times slower
Setting up 4x slowdown in chrome performance tools results in 80-100ms total event time (and 60-80 ms of Tree Reconciliation caused by connected components update).
We have a bit more components connected in the live app. So we are getting ~80-100ms lags on everything, including server-side pushes and API responses. Some patterns, like multiple fields + save on blur are really laggy now - as user gets api response from the previous field save while typing a value in new field. App feels to unpredictable lagging for the end user.
The root cause seems to be state passed via store provider in v.6 that leads to full tree traversal on store change in React 16
Any ideas how to fix that? Right now the only workaround is to stay on 5.1.1.
Another drawback of v6 behavior is mass unrelated updates highlight in React dev tools, as it breaks the common way of finding unwanted components updates, but that is not as critical as performance degradation for me.
We had a lengthy chat with @markerikson yesterday. Our current recommendation is to revert to subscriptions, but the v4 kind — not v5. To enforce top down flow, use batchedUpdates.
To fix tearing we could add some band-aid, like Relay does. IIRC it reads a “version” and if it detects a different store version between renders, it forces a sync update.
In longer term we’ll want something different but I think this will check most boxes now and will be fast.