[Discussion] refactor: optimize freeze state management in DelayedFreeze component #3514
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
We're facing a performance issue which finally proved it can be mitigated by adjusting the logic of the
DelayedFreezecomponent. The issue details are as follows.However, the problem here is that,
setTimeout(..., 0)setTimeout(..., 0)setTimeoutimplementation from the react-native, for the above twosetTimeout(..., 0)invocations, whose scheduled async callbacks are possible to get executed in the single tick, that means, we're possibly updating the state for the screen A and freezing the screen A nearly simultaneously, finally, maybe due to certain kind of race condition issue in the ReactSuspensecomponent or in the React concurrent mode implementation, we found there would be a looks like cyclic JS code execution which causes the app to keep running with a high CPU consumption and the app screen loses responsiveness to the user interactions.This issue might not happen every time when we do the same screen navigation, but the happening possiblity is not low in our app, after deep investigation we found the changes in this PR works well at most scenarios(at least we didn't encounter this performance issue anymore) and is able to avoid the similar issues from the root.
Let's back to the current implementation of delaying the freezing with the
setTimeout(..., 0), I saw the comment says as follows.However actually shoudn't the
setTimeout(..., 0)allow multiple times of rendering instead of only one time before freezing? Conversely, seems that simply utilizing theuseEffectto delay the freezing could really achieve the intention of allowing just one more time render before freezing the screen.Finally, overall the principle behind this PR is seperating the screen freezing and the screen state updating into different ticks as much as possible, even though the real cause might be in the React framework itself intead of the
react-native-screens, but if we could optimize it, then we should do.Anyway, I am not 100% sure my changes won't introduce any new issues, so I'd like have a discussion with you to see if it makes sense. :)
Changes
DelayedFreezecomponent to make it accurately allow just more more render before screen freezing.Screenshots / GIFs
Here you can add screenshots / GIFs documenting your change.
You can add before / after section if you're changing some behavior.
Before
After
-->
Test code and steps to reproduce
Checklist