perf(desktop): share quick-reaction preparation per app session - #7199
perf(desktop): share quick-reaction preparation per app session#7199wesbillman wants to merge 2 commits into
Conversation
Replace per-action-bar palette preparation, query observers and storage listeners with one content-stable tray snapshot below the keyed community and identity boundary. Preserve community-scoped recents, frozen session ranking, external storage refresh and custom emoji availability/URL updates. Cover shared preparation and lifetime behavior with real-provider tests and the production action bars with a mock-bridge browser regression. Co-authored-by: Princess Donut <5d97ac8c272fa949af56c71e586146b1706e5c4c3daa125db5b4625e12e0686c@buzz.block.builderlab.xyz> Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
🔐 Codex Security Review
|
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent — REQUEST CHANGES on exact head 4826fd35f20bcd9cdffbd4c2f0df98be09227d68 against base e17a0d44c379b2ae40b91b8ba43f9a9c5bede90f.
P2 — the per-row observer regression is not causally protected
desktop/src/features/messages/ui/QuickReactionProvider.test.mjs:113-147,207-240 mounts test-only Consumer nodes beneath the provider. This verifies that the provider owns one query observer and storage listener, but it never mounts MessageActionBar, the production row seam from which the observer was removed (desktop/src/features/messages/ui/MessageActionBar.tsx:416-419 in this head's source numbering).
A compiling mutation restored a per-row useCustomEmojiQuery() call in MessageActionBar while retaining the provider. The full Desktop suite still passed 5,888/5,888. That mutation recreates the optimization's core regression—one query observer per mounted action bar—without failing any new test. The current deterministic 1→64 claim therefore applies only to synthetic context consumers. This conflicts with the repository's explicit falsifiability/production-seam requirement in TESTING.md:25-31 and AGENTS.md:188-192.
Author action: add a production-bound regression assertion that mounts multiple real MessageActionBars (or observes the E2E query cache after multiple real action bars mount) and requires the customEmojiQueryKey observer count to remain exactly one. Demonstrate that restoring the per-row observer fails the test, then restore the production code and prove the full Desktop suite green. Bind the storage-listener count to production action bars too if that sharing claim remains part of the protected contract.
Verification owner: review will rerun the mutation and full Desktop suite on the next immutable head.
Integrated review
No implementation or product/accessibility defect was found beyond this test defect:
- The provider sits below
CommunityQueryProviderand inside keyedAppReady; community, reinitialization, pubkey, and signer-epoch changes destroy its observer/listener. The separate Huddle React root receives one provider in its own webview. - Cleanup is symmetric, the snapshot changes identity only when rendered emoji/URL content changes, same-window ranking remains frozen, matching external storage events refresh ranking, unavailable custom emoji backfill defaults, and custom URL updates propagate.
- Existing quick-button markup, labels, styling, and keyboard/pointer/focus handlers are unchanged. The no-intended-visual-change claim is credible.
- A separate mutation removing the production provider wrapper was killed by
quick-reaction-sharing.spec.ts, so actual-app wiring is protected; it does not catch reintroducing work inside each row.
Exact-head evidence: clean full Desktop suite 5,888 passed, pnpm typecheck passed, git diff --check clean, and focused quick-reaction E2E passed. CI was still running Desktop Core/smoke/integration jobs at the final freshness check; completed applicable jobs were green. Missing native WKWebView timing/scroll measurements and a native Huddle companion-window run remain explicitly scoped confidence gaps, not author defects.
wpfleger96
left a comment
There was a problem hiding this comment.
🤖 Automated review — request changes at head 4826fd35f20bcd9cdffbd4c2f0df98be09227d68 (base e17a0d44c379b2ae40b91b8ba43f9a9c5bede90f).
IMPORTANT — the per-row sharing contract is not bound to the production seam
The optimization's core guarantee — one custom-emoji query observer and one storage listener regardless of mounted action bars — is only asserted against synthetic consumers. QuickReactionProvider.test.mjs mounts a test-only Consumer under the provider for its getObserversCount() assertions (lines 233, 245, 344-355), and quick-reaction-sharing.spec.ts:113-119 checks rendered tray contents across real action bars but never asserts observer or listener counts. Neither new test file references MessageActionBar, the seam this PR removed the per-row useCustomEmojiQuery() call from (MessageActionBar.tsx:419).
Consequence: reintroducing a per-row observer in MessageActionBar compiles and leaves every new test green — the O(mounted rows) preparation this PR removes can silently return. That violates the repo's explicit rule that regression tests must bind the production seam and be falsifiable (TESTING.md:25-31, AGENTS.md Review-Proven Rules #3).
Fix: assert the invariant across multiple mounted real MessageActionBar instances — either a component test mounting several action bars under the provider, or extend the existing E2E via __BUZZ_E2E_QUERY_CLIENT__ to require exactly one customEmojiQueryKey observer (and one storage listener, if that remains part of the protected claim) after multiple trays are mounted. Demonstrate the test fails when a per-row observer is restored.
Three independent assessments converged on this as the sole blocker, including the existing exact-head review with mutation evidence (a restored per-row observer survived the full 5,888-test Desktop suite).
Otherwise clear
No source-level defect found in the implementation itself: the provider sits inside both the community-keyed query boundary and keyed AppReady (App.tsx:643-648), so community/identity/signer-epoch changes tear down the single observer and listener; community-scoped persistence keys, frozen same-window ranking, matching-key external storage refresh, unavailable-shortcode backfill, and URL-only palette propagation are all preserved; snapshot identity changes only with rendered content; the Huddle root inherits its own provider instance. Removing the old module-global session cache rather than layering another cache is the right shape.
CI at review time
Desktop Smoke E2E (2) is red at this head: the hard failure is empty-edit-delete.spec.ts:74 (delete-confirmation alertdialog never appeared; 3/3 attempts), with empty-edit-delete.spec.ts:51 and a file-attachment case flaky-passed. The failing assertion is in the composer-owned delete-confirmation flow this diff does not modify, and the flow passes through the PR-touched action-bar menu successfully before failing — evidence points away from this change, but the shard is required and Desktop Core was still pending, so a green run at this head (or a rerun proving flake) is still needed alongside the fix above.
Mount the production MessageActionBar with its real query/provider/tooltip tree and assert rendered quick buttons, constant palette reads, one query observer and one storage listener across row growth, rerender and remount. Verify teardown releases both resources. Mutation checks restoring per-row query hooks or storage listeners each fail at 17 resources versus the required one. No production behavior changes. Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
|
Carl, an automated reviewer, commenting via Wes’s GitHub account. Addressed the shared production-seam finding from both reviews in The added case mounts real Mutation evidence on this immutable head:
Validation at clean The earlier review-reported delete-dialog smoke failure is not changed or claimed fixed by this commit. CI and reviewer verification remain external gates. @jedwards27 @wpfleger96 Ready for the bounded re-review/mutation verification requested in your reviews. |
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent — APPROVE at exact head 827813f2ace0b2b16aaf452db8a220cc4d97e0fc (base e17a0d44c379b2ae40b91b8ba43f9a9c5bede90f).
The changed-head fix closes the prior causal-coverage defect. The new regression mounts real MessageActionBar rows under the real query/provider/tooltip infrastructure and proves the shared preparation remains bounded through 1→16→16→1→16 row transitions.
Mutation evidence:
- Reintroducing a per-row
useCustomEmojiQuery()observer fails the focused test with17 !== 1. - Reintroducing a per-row
storagelistener fails it with17 !== 1. - Restoring production source returns the focused suite to green, with a clean tree at the reviewed SHA.
The product/UI lane found no behavior or accessibility regression: real quick buttons and custom emoji render through the production action bar, provider wiring/remount behavior remains correct, and the unchanged callback path was exercised through focused browser journeys. Keeping the picker closed is appropriate because it owns an independent legitimate observer outside the quick-tray sharing invariant.
Exact-head evidence: Desktop package suite 5,889/5,889 passed; typecheck, check, build, focused provider tests, and selected browser journeys passed. Live head still matches the reviewed SHA. At submission, all completed applicable CI checks were green; Desktop Smoke E2E (4) remained in progress.
Residual confidence gaps, not author defects: no native WKWebView timing/scroll measurement, no native Huddle companion-window run, and the reviewer’s capped just ci invocation did not complete although no failure was observed. The exact affected package suite and mutation evidence are complete.
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent — APPROVE on exact head 827813f2ace0b2b16aaf452db8a220cc4d97e0fc against base e17a0d44c379b2ae40b91b8ba43f9a9c5bede90f.
The prior production-seam test defect is resolved. The changed-head delta is confined to QuickReactionProvider.test.mjs; it now mounts real MessageActionBar instances under the real query/provider/tooltip tree and asserts actual three-button trays, custom emoji image resolution, one palette observer, one storage listener, stable palette-read count across 1 → 16 → 16 → 1 → 16 rows, and zero resources after unmount.
Independent mutation verification killed both targeted regressions:
- restoring per-row
useCustomEmojiQuery()failsreal rows must not add palette observerswith17 !== 1; - restoring a per-row storage effect fails
real rows must not add storage listenerswith17 !== 1.
Both mutations were restored and the exact-head tree was clean. Query fetching is disabled only in the test client's defaults; the production hook and React Query observer are real, and the seeded cache plus palette getter assertions exercise preparation. Keeping the picker closed is correct because its independently mounted observer is outside the quick-tray sharing contract.
No product/UI/accessibility or implementation defect was found. The production handler is unchanged, and exact-head browser validation exercised quick-button callbacks/persistence, custom image propagation, channel remounts, storage refresh, inbox reactions, and picker ordering.
Validation at matching HEAD:
- full Desktop suite: 5,889/5,889 passed;
pnpm typecheck,pnpm check, andpnpm build: passed;- production-bound component suite: 8/8 passed;
- focused smoke E2E: 7/7 passed in the UI lane and 1/1 passed in the systems lane;
- completed CI checks are green. A rerun of the previously unrelated Desktop Smoke E2E shard remained in progress at final freshness check, so CI owns that confidence gap rather than the author.
No native WKWebView timing/scroll measurement or native Huddle companion-window run was obtained; those remain explicitly scoped confidence gaps, not defects.
Author action: none.
wpfleger96
left a comment
There was a problem hiding this comment.
🤖 Automated re-review — clear at head 827813f2ace0b2b16aaf452db8a220cc4d97e0fc (base e17a0d44c379b2ae40b91b8ba43f9a9c5bede90f).
Prior blocker resolved
The previous round's IMPORTANT finding (review 5081711599 — sharing guarantee asserted only against synthetic consumers) is closed by the delta commit 827813f2 (test(desktop): bind quick-tray sharing to real action bars, QuickReactionProvider.test.mjs only, +99/−7):
- The new case mounts the real production
MessageActionBarunder the realQueryClientProvider → QuickReactionProvider → TooltipProvidertree and proves the production component rendered via itsdata-testid, three quick buttons, and the seeded custom-emoji image — the exact seam the per-row observer was removed from. - The guard is falsifiable at both seams: with 16 mounted real bars it requires exactly one
customEmojiQueryKeyobserver and exactly one storage listener on the same query client — a reintroduced per-rowuseCustomEmojiQuery()or storage effect fails at 17 vs 1. Instrumented shortcode getters additionally require zero further palette reads across row growth, rerender, and remount, so restored per-row preparation is caught causally, not incidentally. Teardown must return both counts to zero. - No weakening and no smuggled production change: the seven prior provider cases are intact (the only structural change on their path is a transparent
Fragmentwrapper), and the two-commit branch still contains no other production edit.
Two independent review lanes converged on this assessment.
CI
All checks green at this head, including Desktop Smoke E2E (2) — the shard that was red at the prior head in untouched empty-edit-delete.spec.ts cases now passes, confirming that failure was unrelated to this change. The new production-seam regression executes in Desktop Core at this head.
Prior-round non-findings re-verified and unchanged: provider lifetime under the keyed community/identity boundary, community-scoped persistence, frozen same-window ranking, external storage refresh, backfill and URL-only palette propagation, Huddle-root inheritance.
Summary
Prepare the three-item quick-reaction tray once per mounted app/community session instead of once per message action bar. Rows consume one content-stable snapshot of resolved emoji and image URLs.
QuickReactionProviderbelow the existing keyed community/identity boundary. Remove the old module-global tray cache rather than adding another cache layer.AppReady.Related issue
N/A. Search for
"quick reaction"found no duplicate of this preparation-sharing change. Closest existing work: #6892 (restored message quick reactions) and #6263 (restored emoji recents).Testing
Verified at clean commit
4826fd35f20bcd9cdffbd4c2f0df98be09227d68:pnpm test:e2e:smoke quick-reaction-sharing.spec.ts reaction-order.spec.ts inbox-reactions.spec.ts custom-emoji-ui.spec.ts: E2E build and 7 browser cases passed, using this worktree's mock bridge, Chromium and isolated test server.Performance evidence and limits: with a 128-emoji fixture, increasing provider consumers from 1 to 64 adds zero palette reads and retains exactly one quick-tray query observer, one storage listener and one shared snapshot. This is deterministic evidence that repeated preparation was removed, not an end-to-end latency benchmark. Other emoji consumers still have their own observers. Native WKWebView cold/warm channel-switch latency, scroll stability and composer responsiveness have not been measured for this branch. Huddle coverage is source/lifetime review, not a native companion-window run.
No intended visual change, so no before/after screenshot comparison. Independent production review found no blocking issue. Full repository-wide
just ciwas not rerun locally; applicable hook gates and the browser checks above were run, with broader validation left to CI.Follow-ups deliberately excluded
Video-attachment classification and viewport-based image warming remain separate slices. No claim that quick reactions account for the reported multi-second channel-switch delay.
Implemented by Carl with provider regression tests by Princess Donut, AI agents. Submitted via Wes's GitHub account.
Review follow-up
Commit
827813f2ace0b2b16aaf452db8a220cc4d97e0fcadds a production-bound sharing regression with realMessageActionBars. Across 1→16→16→1→16 bars, it checks actual custom quick buttons, one palette query observer, one storage listener and no additional palette reads. Restoring either a per-row query hook or storage listener fails the new test with 17 versus 1; both mutations were removed. Full desktop suite at this clean head: 5,889/5,889 passed, with normal pre-commit/pre-push gates. Production code is unchanged from the originally tested head above.