Refactor ProfileView.onAppear code #1748
Merged
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.
Issues covered
Another attempt at fixing https://github.com/verse-pbc/issues/issues/171 and https://github.com/verse-pbc/issues/issues/175
Description
Story time:
After merging #1744 I had Rabble test the build to see if it fixed the performance issue they were having. It did not. Then this morning while looking into Itunu's comment on #1744 I noticed that the profile photos weren't loading in the home feed on a fresh install. I confirmed that this was caused by #1744 so I reverted it.
I came up with a new theory for the cause of the ProfileView refresh loop. There are a couple issues here:
This PR sets out to solve issue 1, and I'm hoping that in doing so we maybe solve 2 as well. Issue 1 is somewhat well known. SwiftUI's
TabView
calls onAppear for all the tabs all the time. We worked around this in the Home, Discover, and Notifications tab by keeping track of@State var isVisible
and only firing analytics and other things when the tab actually goes from not being visible to being visible. We never did this on the ProfileView because unlike the others it isn't only presented by the TabView. It's also pushed onto the navigation stack from wherever you tap on an author's name.I started by refactoring the
isVisible
code into a nice view modifier. Then I adopted that modifier on all the tabs. This allowed me to fire a new "Profile Tab Opened" event when the tab is selected. To track the other times the profile view is opened I added an analytics call to file "Profile View Opened" in the Router. I also renamed some of the other analytics events to make it clear that they don't only fire when the user taps the tab, it fires any time that view appears, even when navigating back from a pushed view.I also refactored the call to
downloadAuthorData()
inProfileView
so that it is called in a.task {}
modifier instead of.onAppear {}
. This means it will only be called when SwiftUI observes a change in one of its variables, i.e. the author being displayed. This is the change that I'm hoping fixed the weird infinite loop race condition. My working theory is that the race condition had something to do withonAppear()
triggeringdownloadAuthorData()
, thendownloadAuthorData()
somehow causing the author to be mutated enough thatAppView
would redrawProfileTab
, which causedonAppear()
to fire again.How to test
I guess the main test would be tapping all the tabs rapidly and seeing if you can trigger the infinite loop where the parse queue fills up and the CPU gets stuck at 100%.