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

Feat: cached safe overviews #4221

Merged
merged 7 commits into from
Sep 25, 2024
Merged

Conversation

schmanu
Copy link
Member

@schmanu schmanu commented Sep 20, 2024

What it solves

Rewrites useSafeOverviews hook using RTK query enabling:

  • caching
  • more efficient batching of requests
  • easier interface to query safe overviews

The goal is to have two hooks:

  • One that loads a single Safe overview for any Safe.
  • One that loads multiple Safe overviews

Both of them use a shared queue that waits for more requests to come in for 50ms or triggers a requests once 10 requests are in the queue.

Other changes

  • Do not fetch Safe overviews for undeployed Safes

How to test it

While monitoring the outgoing network requests via e.g. developer tools in the browser:

  • Connect a wallet and open the sidebar / account list.
  • Select and open any Safe
  • Now re-open the sidebar.
  • This should not trigger any new requests as the data should still be cached.

Stats

On a full sidebar with multichain Safes this optimization with a fresh browser state reduces the safe overview requests from 38 to 18.

Checklist

  • I've tested the branch on mobile 📱
  • I've documented how it affects the analytics (if at all) 📊
  • I've written a unit/e2e test for it (if applicable) 🧑‍💻

@schmanu schmanu changed the base branch from dev to epic/multichain-safes September 20, 2024 14:43
Comment on lines 67 to 73
nextBatch.forEach((item) => {
const overview = overviews.find(
(entry) => sameAddress(entry.address.value, item.safeAddress) && entry.chainId === item.chainId,
)

item.callback({ data: overview })
})
Copy link
Contributor

Choose a reason for hiding this comment

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

since we're already calling the item.callback in the catch block, shouldn't this line be inside the try block?

Copy link

github-actions bot commented Sep 25, 2024

Copy link

github-actions bot commented Sep 25, 2024

📦 Next.js Bundle Analysis for safe-wallet-web

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 990.09 KB (🟡 +35.56 KB)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

Twelve Pages Changed Size

The following pages changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/ 511 B (🟢 -24.37 KB) 990.59 KB
/address-book 26.09 KB (🟡 +5 B) 1016.18 KB
/apps/open 54.74 KB (-1 B) 1.02 MB
/balances 31 KB (🟡 +73 B) 1021.09 KB
/balances/nfts 19.18 KB (-1 B) 1009.27 KB
/home 60.96 KB (🟡 +744 B) 1.03 MB
/new-safe/advanced-create 36.49 KB (🟡 +1.36 KB) 1 MB
/new-safe/create 35.75 KB (🟡 +1.35 KB) 1 MB
/new-safe/load 16.41 KB (🟡 +10 B) 1006.5 KB
/settings/notifications 27.02 KB (-2 B) 1017.11 KB
/settings/setup 35.98 KB (🟡 +5 B) 1 MB
/transactions/tx 21.07 KB (-2 B) 1011.16 KB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

Copy link

github-actions bot commented Sep 25, 2024

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements
78.22% (+0.04% 🔼)
12419/15876
🔴 Branches
58.17% (+0.03% 🔼)
3224/5542
🟡 Functions
65.7% (+0.12% 🔼)
1961/2985
🟡 Lines
79.69% (+0.05% 🔼)
11205/14061
Show new covered files 🐣
St.
File Statements Branches Functions Lines
🟡
... / index.ts
68.97% 100% 50% 73.08%
🟢
... / safeOverviews.ts
100% 100% 100% 100%
🔴
... / ofac.ts
46.43% 0% 25% 54.55%
🟢
... / safePass.ts
90.91% 75% 50% 88.89%
Show files with reduced coverage 🔻
St.
File Statements Branches Functions Lines
🟢
... / useLoadBalances.ts
91.11% (-2.22% 🔻)
66.67% 100% 95%

Test suite run success

1548 tests passing in 206 suites.

Report generated by 🧪jest coverage report action from a84a4e0

@schmanu schmanu marked this pull request as ready for review September 25, 2024 09:01
Copy link
Member

@usame-algan usame-algan left a comment

Choose a reason for hiding this comment

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

Great idea to batch and cache these requests! We should do the same for useAllOwnedSafes.

() => multiChainGroupSafes.filter((safe) => undeployedSafes[safe.chainId]?.[safe.address] === undefined),
[multiChainGroupSafes, undeployedSafes],
)
const { data: safeOverviews } = useGetMultipleSafeOverviewsQuery({ safes: deployedSafes, currency })
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to pass the walletAddress here as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

I do not pass it to have less dependencies and more likely cache hits.
This component is only interested in the signers and the threshold. The wallet address fetches the pending actions which is not needed here.

@@ -53,6 +53,7 @@ const rootReducer = combineReducers({
[ofacApi.reducerPath]: ofacApi.reducer,
[safePassApi.reducerPath]: safePassApi.reducer,
[slices.gatewayApi.reducerPath]: slices.gatewayApi.reducer,
[slices.safeOverviewApi.reducerPath]: slices.safeOverviewApi.reducer,
Copy link
Member

Choose a reason for hiding this comment

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

Wdyt about making this part of the gatewayApi slice to keep all related calls in one place? The SafeOverviewFetcher could be moved to its own file.

Copy link

@schmanu schmanu merged commit ea83b21 into epic/multichain-safes Sep 25, 2024
13 checks passed
@schmanu schmanu deleted the feat/cached-safe-overviews branch September 25, 2024 13:58
@github-actions github-actions bot locked and limited conversation to collaborators Sep 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants