fix(ui): keep the home transaction list responsive during sync - #792
Merged
QuantumExplorer merged 1 commit intoJul 9, 2026
Conversation
Scrolling the home transaction list stuttered whenever the wallet was syncing, and the list rendered empty for ~0.7s at startup. Three causes, three fixes: - Every SwiftData save (one per SPV/BLAST batch) plus each balance notification triggered an immediate full reload. All wallet-change triggers now funnel into one PassthroughSubject throttled to a reload per second (latest: true, so the trailing batch always lands; a lone event while idle still passes through immediately). The save notification also previously arrived via RunLoop.main, which runs in the default runloop mode only — saves during a drag queued up and burst right as the finger lifted. - Each reload fetched and wrapped ALL transactions on the main thread (DispatchQueue.main.sync + mainContext), including a per-tx SwiftData relationship walk for CoinJoin classification — far beyond a frame budget mid-scroll. SwiftDashSDKWalletSource now grabs only the @mainactor host handles in a brief main hop and runs the fetch + wrap on the caller's thread with a private ModelContext. Safe because Transaction snapshots every field at wrap time, and a private context reads the last saved state — exactly what the did-save trigger guarantees exists. - resolveMetadata copied every provider's whole metadata dictionary through its serial queue per transaction per reload; the reload loop now snapshots each provider once (gift-card filter included). Startup pop-in: the first load was only scheduled behind the 0.5s sync-state debounce; init now kicks it off immediately (nothing to coalesce yet, and the fetch is off-main anyway). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughChangesWallet data flow
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant WalletNotification
participant HomeViewModel
participant SwiftDashSDKWalletSource
participant ModelContext
WalletNotification->>HomeViewModel: enqueue wallet reload request
HomeViewModel->>HomeViewModel: throttle latest request
HomeViewModel->>SwiftDashSDKWalletSource: reload transaction data
SwiftDashSDKWalletSource->>ModelContext: fetch and wrap transactions
ModelContext-->>SwiftDashSDKWalletSource: return persistent transactions
SwiftDashSDKWalletSource-->>HomeViewModel: return wrapped transaction rows
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Member
Author
|
@coderabbitai review |
✅ Action performedReview finished.
|
QuantumExplorer
deleted the
claude/transaction-scroll-responsiveness-50f03a
branch
August 7, 2026 08:22
This was referenced Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
Scrolling the home transaction list was janky, especially while the wallet was syncing, and (secondarily) the list rendered empty for ~0.7s at startup before rows popped in.
Causes
DSWalletBalanceDidChangefired an immediate full reload of the tx list; during sync that's several full reloads per second. The save notification was also delivered viaRunLoop.main(default runloop mode only), so saves arriving mid-drag queued up and burst right as the finger lifted, stalling the hand-off frame.SwiftDashSDKWalletSourcefetched and wrapped all transactions throughDispatchQueue.main.synconmainContext, including a per-tx SwiftData relationship walk (outputs → coreAddress → account) for CoinJoin classification — far beyond a frame budget, landing repeatedly mid-scroll.resolveMetadatacopied each metadata provider's entire dictionary through its serial queue per transaction per reload (O(n) queue hops + copies).Fixes
PassthroughSubjectthrottled to one reload per second (latest: trueguarantees the trailing batch lands; a lone event while idle passes through immediately).SwiftDashSDKWalletSourcenow reads only the@MainActorhost handles (modelContainer+walletId) in a brief main hop, then runs the fetch + wrap on the caller's thread with a privateModelContext— reloads never block the main thread. Safe becauseTransactionsnapshots every UI-read field at wrap time, and a private context reads the last saved state — exactly what the did-save trigger guarantees exists. Stale "main-bound" doc comments updated to match.initnow kicks it off immediately.Verification
dashpayscheme build (arm64 simulator, per DASHSYNC_MIGRATION verification standard).🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Performance