-
Notifications
You must be signed in to change notification settings - Fork 73
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
Prevent setting state for values that have not changed. Add additional Onyx debugging metrics. #185
Conversation
…o update Add test add dequal and debug setState calls remove throw Add setState logging methods remove dequal for now new PR Only include difference not previous/new value
bcd0995
to
d4ef666
Compare
I'm not familiar with onyx but knowing other state management libraries I'm wondering if |
Yeah, I think we can walk through that as an exercise. Probably first we need to understand whether we are passing around object references or new copies in some places to begin with. I am not actually 100% sure about this... All the data a component initially receives will come from here: Lines 563 to 574 in 3f936d9
This next part is confusing because we have two kinds of "subscribers" the collection or just normal key. If we have a normal key the value in the cache it would be returned to the component otherwise we get it from storage, put it in the cache, and then return it: Lines 45 to 62 in 3f936d9
When it goes in the cache we don't do anything special to it so it should be a good reference react-native-onyx/lib/OnyxCache.js Lines 92 to 95 in 3f936d9
If the key we are subscribing to is normal (non-"collection") we just set the value directly to state: Lines 571 to 572 in 3f936d9
Line 442 in 3f936d9
And the reference to these simple object I think should survive and be sent to the component: react-native-onyx/lib/withOnyx.js Lines 90 to 103 in 3f936d9
"Collection keys" work a bit different because we collect all the keys and then reduce them into a new object here: Lines 484 to 488 in 3f936d9
Then the whole big object is set to a single That's just to give an idea of the references the components start with: Next we should look at how they are updated... If a single key with object value is changed via a Lines 761 to 771 in 3f936d9
Finally this new object is saved: Line 816 in 3f936d9
And then stored in the cache + subscribers are notified with the new value: Lines 685 to 686 in 3f936d9
I think at this point it's safe to say that for the simple values this will always create a new object in the cache. So even though we take the value from the cache and pass it to a subscriber here without modifying it when it is pulled from the cache: Lines 411 to 413 in 3f936d9
So if we were to look at And if the key we changed belongs to a collection and the subscriber wants all the data then we do this: Lines 398 to 406 in 3f936d9
Which in the case of Hopefully that's not TMI and helps give some ideas about how things work. |
Actually going to split these debugging metrics and anything related to equality checks into separate PRs. |
Details
There are many calls to
setState()
in Onyx that can be avoided. The cost to calculate whether they have changed is lower than the cost to re-render the components that are subscribing to them. Therefore, it makes sense to use an optimized equality check to see if something has changed before we update a component.I also added metrics that give us insights into why the
setState()
call is happening which can be enabled by using theONYX_METRICS=true
flag in the.env
file.Note: These metrics are currently broken on web due to some unrelated issue. And removing the
applyDecorators()
method will fix the build and allow our new logs to appear.Metrics
FCP/LCP/etc on Web
without checks
with checks
Chat Switch Time on Web
without
dequal
checks:with
dequal
checks:There's ~ 90 ms improvement in the chat switching from reducing set state.
So far... not super impressive... but check out Android profiles on chat switching...
Chat Switch Time on Android
without checks
with checks
That's 664 ms difference which is pretty great.
Related Issues
Automated Tests
Linked PRs