perf(messages): index the emoji catalog for reaction lookups - #333
Conversation
Every message row resolved its quick reactions by scanning the whole custom emoji catalog, building a string per entry, on every render. Index each catalog snapshot once and skip the lookup for native emoji. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: murderbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3c2ef35e9c
ℹ️ 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".
| ); | ||
| } | ||
|
|
||
| const catalogIndexes = new WeakMap< |
There was a problem hiding this comment.
Add the required Signed-off-by trailer
The target commit contains no Signed-off-by trailer. Any PR containing this commit will therefore violate the repository's per-commit DCO requirement and fail the hosted DCO Check; recreate the commit with the actual author's verified name/email and sign-off.
AGENTS.md reference: AGENTS.md:L151-L161
Useful? React with 👍 / 👎.
wesbillman
left a comment
There was a problem hiding this comment.
Star Lord — automated source review via Wes's account
No actionable findings. The change meets the 9/10 source-review bar for minimalness, elegance, and correctness within this focused optimization.
Reviewed head 3c2ef35e9cecb03d826152dcc16ce331982fe710 against base/merge-base 85d6bf82c54d1c8d930d58444597a1fe31cc8975 using pinned, blob-hash-verified source; no dirty working-tree inputs.
The lookup replacement preserves the supported catalog contract:
emoji.ts:10–28normalizes shortcodes and freezes entries;emoji-directory.ts:72–89deduplicates winners and publishes a fresh frozen array. Consequently, indexing by array identity does not reuse stale entries after catalog replacement, and Map lookup does not change duplicate-selection behavior.- Each session owns its directory (
session.ts:563,1557); clear/dispose replace the entries array. The module-level WeakMap shares work across rows without keying different communities by shortcode alone. - Native reactions bypass the catalog, case-insensitive custom lookup is retained, and historical pills still toggle their event-local emoji URL (
MessageReactions.tsx:310), not the current catalog URL.
Read the repository instructions, contribution/channel contracts, and Buzz vision documents. Existing test source covers native toggles, current-vs-historical custom URLs, normalization, replacement, and session isolation. This PR adds no tests; I did not execute any tests, PR code, or application workflow, and did not reproduce the reported performance measurements.
One exact-head CI snapshot at 2026-09-28 02:53:53 UTC showed JavaScript, browser measurements, DCO, Semgrep, and zizmor successful; browser journeys and Rust/tool integration were still running, and Windows validation was skipped. CI completion, runtime behavior, and release-build performance remain unverified. This is a non-blocking COMMENT review, not approval or merge authorization.
* origin/main: (45 commits) Use Blue 11 links with Blue 3 hover and explicit contrast exceptions (#322) perf(messages): index the emoji catalog for reaction lookups (#333) Polish search palette and add conversation search (#340) Use step-ten avatar colors with contrasting outlines (#320) Keep profile avatar cutouts transparent and align the header gutter (#319) Restore sidebar status icons beside names (#316) docs(mentions): specify portable mention rules (#343) fix(agents): wait for native host operations (#331) Simplify channel templates and report setup failures accurately (#318) feat(agents): Harnesses Goose install (slice 3/5) (#279) feat(agents): Harnesses status card in Settings (slice 2/5, stacked on #272) (#277) Fix timer operation ownership and stabilize timing regressions (#317) Restore cached workspace before relay startup (#311) test(browser): wait for the app's own quota cooldown before retrying (#284) docs: define Harnesses setup and global agent defaults (#272) Make mention choices consistent and stable (#258) Discover saved relay agents without changing the page (#224) feat: add persistent dev log levels and relay traffic summaries (#306) Polish inline message reactions and previews (#213) feat(identity): add native macOS import, creation and backup (#308) ... Signed-off-by: Sol <49aa1f65411fd096d2e2ec144f1e7aa36fdc76d1b907cfdf7be000c66f9d3b8e@buzz.block.builderlab.xyz> # Conflicts: # src/bundled/agents/AgentCard.tsx # src/bundled/agents/AgentsPage.tsx
* origin/main: (36 commits) Delay message timestamp tooltips by 500 ms (#321) Use Blue 11 links with Blue 3 hover and explicit contrast exceptions (#322) perf(messages): index the emoji catalog for reaction lookups (#333) Polish search palette and add conversation search (#340) Use step-ten avatar colors with contrasting outlines (#320) Keep profile avatar cutouts transparent and align the header gutter (#319) Restore sidebar status icons beside names (#316) docs(mentions): specify portable mention rules (#343) fix(agents): wait for native host operations (#331) Simplify channel templates and report setup failures accurately (#318) feat(agents): Harnesses Goose install (slice 3/5) (#279) feat(agents): Harnesses status card in Settings (slice 2/5, stacked on #272) (#277) Fix timer operation ownership and stabilize timing regressions (#317) Restore cached workspace before relay startup (#311) test(browser): wait for the app's own quota cooldown before retrying (#284) docs: define Harnesses setup and global agent defaults (#272) Make mention choices consistent and stable (#258) Discover saved relay agents without changing the page (#224) feat: add persistent dev log levels and relay traffic summaries (#306) Polish inline message reactions and previews (#213) ... Signed-off-by: Sol <49aa1f65411fd096d2e2ec144f1e7aa36fdc76d1b907cfdf7be000c66f9d3b8e@buzz.block.builderlab.xyz> # Conflicts: # src/bundled/agents/AgentEditor.tsx # src/bundled/profiles/ProfileAgentIdentity.test.tsx
What
Every message row renders the hover quick-reaction buttons (👍 ❤️ 😂). To decide whether each is a custom emoji,
MessageReactionControlsrancatalog.entries.find(e =>:${e.shortcode}:=== content.toLowerCase())over the whole custom-emoji catalog — three full scans per row, on every render, allocating a string per entry. Native emoji never match, so every scan was a worst case.This change:
Maponce per catalog snapshot (cached in aWeakMapkeyed on the frozen snapshot fromemoji-directory.ts):, so native emoji never touch the catalogSingle file:
src/features/messages/MessageReactions.tsx. Rendered output is unchanged.Evidence
Headless Chromium via Playwright against
just web(Vite dev build), cold start → open 4 channels → scroll history, DevTools trace with CPU samples, then attributed every sample inside 50 ms+ main-thread tasks. Two runs each, back to back, same account.MessageReactionControlsself+childrenAbout half of what remains is React dev-only runtime (
jsxDEV, dev react-dom), absent in release. The scan removed here is app code, so the ~0.5 s saving should carry over to release builds. The workload was a light account (4 channels); cost scales with rendered rows × catalog size.Checks
tscand biome cleansrc/features/messagesvitest: 47 files, 682 tests pass🤖 Generated with Claude Code