Repository navigation
perf(mobile): memoize npub labels - #9137
Conversation
Identity views label every roster member without a profile name by npub on each rebuild. On a 5.9k-member channel that bech32 work dominated 13 scope recomputes while opening it. Keep a bounded hex-to-npub map. Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz> Signed-off-by: Tom Brow <tomb@squareup.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🔐 Codex Security Review
Review SummaryOverall Risk: NONE
FindingsNo concrete security, correctness, or reliability findings were identified. Notes
Generated by Codex Security Review | |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d2ce12d0d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| String _encodeNpub(String hexPubkey) { | ||
| final cached = _npubs[hexPubkey]; | ||
| if (cached != null) return cached; | ||
| if (_npubs.length >= _npubLimit) _npubs.clear(); |
There was a problem hiding this comment.
Avoid clearing the entire npub cache at capacity
When a channel still has more than 8,192 unnamed members, clearing the entire map causes repeated same-order roster scans to thrash instead of being memoized. For example, an 8,193-key scan ends with only the last key cached; the next scan fills the map with that tail entry plus the first 8,191 keys, clears it before reaching the cached tail, and therefore re-encodes every key again. Larger communities can consequently retain the UI-isolate stalls this change is intended to remove; use a bounded policy that preserves useful entries across over-capacity scans and cover a roster just above the limit.
AGENTS.md reference: AGENTS.md:L23-L30
Useful? React with 👍 / 👎.
Clearing at the limit re-encoded every key of a larger roster on each scan. Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz> Signed-off-by: Tom Brow <tomb@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
No blockers. The memo is keyed on the normalized lowercase hex, only stores validated keys, is bounded, and labels are unchanged; the tests cover reuse and the full-cache case. CI is green.
Carl, an automated reviewer, commenting via Wes's GitHub account.
* origin/main: (60 commits) feat(cli): user status expiry and status read (#8777) feat(cli): send a thread message to the channel (#8778) feat(relay): add kind 30180 custom emoji entry (#8783) feat(cli): read-only unread state (NIP-RS) (#8789) feat(cli): report a message to relay moderators (#8829) buzz-db: read explicit #h sets one channel at a time (#9110) feat(cli): list huddles and their participants (#8830) docs(agents): add open-source boundary and drop private repo list (#9114) fix(mobile): answer push snapshot bridge calls at user-initiated QoS; report hop latency on callback timeout (#8916) test(mobile): lock in invite-page and bare-host community link entry (#9047) fix(desktop): keep an own send out of the frozen timeline tail (#9095) fix(db): end each table's maintenance transaction before the next (#9096) perf(mobile): show a static placeholder for posterless videos (#9138) fix(desktop): compensate head trims from the unclamped scroll offset (#9094) fix(relay): read kind:39000/39001 inputs behind the replacement lock (#9035) fix(db): unlock the storage-accounting lease before its session closes (#9097) test(relay,db): remove three timing races from Postgres and E2E tests (#9098) fix(db): keep busy-reader history reads off the writer and cap them per pod (#9132) perf(mobile): memoize npub labels (#9137) mobile: stop re-parsing messages on every resume (#9140) ... Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Signed-off-by: Will Pfleger <wpfleger@block.xyz> # Conflicts: # crates/buzz-cli/src/commands/users.rs
Opening a big channel on mobile stalls while member labels resolve. On an iPhone 12 mini (wired Profile build of main 120d75d), opening a 5,892-member channel had frames of 217, 113 and 101 ms. The channel identity scope recomputed 13 times during the open as profiles arrived, 25 to 35 ms each: 235 ms of 1,755 ms UI CPU, 190 ms of it bech32 encoding. Every recompute labels each member without a profile name by npub (
missingOwnerProfiles→IdentityNameSources.factFor→shortPubkey→fullNpub), and encoded the same keys again. The same chain cost 152 ms in a 15 s resume with the channel open.fullNpubnow memoizes encodings by hex key, bounded at 8,192 entries. Once full it keeps what it has, so a roster larger than the limit still reuses most of its encodings. Labels are unchanged.Validation
fullNpub reuses the encoding of a key it has already encodedfails without the memo;a roster larger than the cache still reuses its encodingsfails if the cache clears when full.shortPubkeyover 5,900 random keys: 53.5 ms on the first pass, about 3.1 ms on later passes.push_lease_revocation_outbox_test, which also fail on main. Analyze clean.npub194z...aq3k).🤖 Generated with Claude Code