Dedupe TCARouter ViewStore to improve rendering performance #20
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.
While playing around with TCARouter I noticed some odd SwiftUI bugs occurring. I added a debug() to one of the child ViewStores that is contained in a TCACoordinator flow and noticed it was rerendering all child views when any state in the entire flow changed. Looking deeper I noticed the WithViewStore at the root of the TCARouter did do any scoping or deduping for the greater flow state it owned causing this over rendering of its views.
My PR updates the highest level viewStore to only re-render when the actual route path changes, allowing child views to better control when they re-render. This seems to be the best practice to avoid over drawing and is similar to what other higher level store helpers like SwitchStore do as well (ht to @stephencelis for the wonderful idea).
You can confirm the improvement by adding debug() helpers on the higher level WithViewStore and making sure it only emits when the actual routes change (push, pop, present) but not when some internal state of an individual screen changes.
Small note: If the library eventually supports changing routes in place (rather than popping, pushing, presenting, etc) it might make sense to make this smarter by requiring some sort of identity for each screen so that the higher level view store re-renders even if the styles stay the same.