Skip to content
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

Performance improvements #6376

Merged
merged 26 commits into from
Jan 10, 2025
Merged

Performance improvements #6376

merged 26 commits into from
Jan 10, 2025

Conversation

christianbaroni
Copy link
Member

@christianbaroni christianbaroni commented Jan 1, 2025

Fixes APP-1603
Fixes APP-2249

What changed (plus any additional context for devs)

Memory Management:

  • Resolves memory bloat in userAssets stores by restructuring a) the store cache, and b) hidden balance management
  • The previous Map structure was resulting in all userAssets stores accessed during runtime being permanently retained in memory — now holding only one store at a time
  • useWalletsHiddenBalances was looping through all wallets on app launch, causing every userAssets store to be accessed and thus held in memory
    • Now, hidden asset balances are summed any time a specific wallet's assets are synced to Zustand, and any time setHiddenAssets is called
    • That total is saved to userAssetsStoreManager's persisted state, allowing all hidden wallet balances to be read from a single source, with no need to loop through individual stores or wallets
  • All told, these changes bring around a ~50-60% reduction in memory usage

queryClient:

  • Implements a custom MMKVPersister with an 8s trailing debounce, which seems to be lighter than the old async persister
  • Adds a global 4-week maxAge to restrict query cache growth

JS thread Shared Value Reads:

  • The first run of any useAnimatedStyle or useDerivedValue is executed on the JS thread
  • The first run can be detected by checking if _WORKLET is false, allowing bypassing these expensive reads if you can set the hook's initial return value through other means
  • These changes bypass the vast majority of JS thread SV reads throughout the browser, which reduces thread blocking post app launch and during browser tab creation

Android UI Fixes:

  • Fixes bottom bar handling and boot jank
    • Fixes device height and safe area determinations, which were previously inconsistent in what was considered part of the safe area vs. part of the device height
    • Provides the SafeAreaProvider with initialWindowMetrics which on Android prevents layout shift on app launch
    • Sets the bottom bar background to transparent when button navigation isn't being used
      -Now correctly handling dimensions regardless of whether the device uses button navigation

Package Upgrades:

  • Skia: 1.5.101.8.2
  • Reanimated: 3.16.33.16.6
  • Updates react-fast-compare, use-deep-compare
  • Removes @tanstack/query-async-storage-persister

Additional Changes

  • Reduces meteorology cache time from infinity to 36s
  • Memoizes favorites to prevent unnecessary recalculations
  • Now conditionally loading boot-related modules
  • Cleans up AppDelegate methods and warnings, along with a couple Xcode performance warnings

Screen recordings / screenshots

What to test

@christianbaroni christianbaroni added the performance performance related improvements label Jan 1, 2025
Copy link

socket-security bot commented Jan 1, 2025

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@shopify/[email protected] None 0 315 MB shopify-dep
npm/[email protected] None 0 14.2 kB lukeed
npm/[email protected] None 0 32.3 kB alexsandiyarov

🚮 Removed packages: npm/@shopify/[email protected], npm/@tanstack/[email protected], npm/[email protected], npm/[email protected], npm/[email protected]

View full report↗︎

The previous Map structure was resulting in all userAssets stores accessed during runtime being held permanently in memory.

On top of that, `useWalletsHiddenBalances` was repeatedly looping through all wallets on app launch, causing every userAssets store to be accessed and thus held in memory.

Now, hidden asset balances are summed any time a specific wallet's assets are synced to Zustand, and any time `setHiddenAssets` is called. That total is saved to `userAssetsStoreManager`'s persisted state, allowing all of the user's hidden wallet balances to be read from a single source, with no need to loop through individual stores.

The tradeoff here, which I think is acceptable, is that users will temporarily see their hidden balances reflected in each wallet's total balance, until that wallet next fetches assets. That seems benign enough to forgo a migration.
Copy link

linear bot commented Jan 7, 2025

@brunobar79 brunobar79 added the release for release blockers and release candidate branches label Jan 8, 2025
@DanielSinclair
Copy link
Contributor

Super speedy ⚡

@alex-grover
Copy link

lgtm

@ccarella
Copy link

ccarella commented Jan 8, 2025

lgtm. 🚢

@mikedemarais
Copy link
Contributor

lgtm 🤠

@horsefacts
Copy link

lgtm 🐎

Copy link
Contributor

@skylarbarrera skylarbarrera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

export const persistOptions: Omit<PersistQueryClientOptions, 'queryClient'> = {
persister: asyncStoragePersister,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦‍♂️

@leeknowlton
Copy link

lgtm

Copy link

@datadanne datadanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

src/react-query/queryClient.ts Outdated Show resolved Hide resolved
src/react-query/queryClient.ts Outdated Show resolved Hide resolved
src/state/assets/userAssets.ts Outdated Show resolved Hide resolved
`chainBalances.size` will only be zero if `setUserAssets` has never been called for the active store.

If `setUserAssets` has been called, `chainBalances` will be populated, regardless of whether the wallet has assets.
The first run of any `useAnimatedStyle` or `useDerivedValue` is executed on the JS thread.

The first run can be detected by checking if `_WORKLET` is `false`, which allows bypassing expensive JS thread SV reads if you can set the hook's initial return value through other means.

These changes bypass the vast majority of JS thread SV reads throughout the browser, which reduces JS thread blocking post app launch and during browser tab creation.
Prevents tab switch gestures from activating when the browser search UI is open
- Fixes Android device height and safe area determinations, which were previously inconsistent in what was considered part of the safe area vs. part of the device height — this was causing various UI dimensions to be miscalculated, for instance browser tab heights
- Provides the `SafeAreaProvider` with `initialWindowMetrics` which on Android prevents layout shift on initial app launch
- Sets the bottom bar background to transparent when button navigation isn't being used
- Now correctly handling dimensions regardless of whether the device uses button navigation
The gesture blocking isn't needed
Copy link
Contributor

@pugson pugson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ship it

@christianbaroni christianbaroni marked this pull request as ready for review January 10, 2025 09:18
@brunobar79
Copy link
Member

Launch in simulator or device for 109107c

@brunobar79
Copy link
Member

Launch in simulator or device for 3412def

Copy link
Contributor

@walmat walmat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link
Member

@derHowie derHowie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

@brunobar79
Copy link
Member

Launch in simulator or device for 6d575d4

@walmat walmat merged commit d312658 into develop Jan 10, 2025
8 checks passed
@walmat walmat deleted the @christian/performance-fixes branch January 10, 2025 22:14
Copy link

linear bot commented Jan 10, 2025

@christianbaroni christianbaroni restored the @christian/performance-fixes branch January 12, 2025 10:03
Copy link

sentry-io bot commented Jan 14, 2025

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ TypeError: Cannot read property 'url' of undefined Search(src/components/DappBrowser/search/Search) View Issue

Did you find this useful? React with a 👍 or 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge when ready performance performance related improvements release for release blockers and release candidate branches
Projects
None yet
Development

Successfully merging this pull request may close these issues.