Skip to content

perf(channels): stop rerendering message rows after each channel switch - #269

Merged
loganj merged 1 commit into
mainfrom
larry/stable-channel-callbacks
Sep 25, 2026
Merged

loganj merged 1 commit into
mainfrom
larry/stable-channel-callbacks

Conversation

@loganj

@loganj loganj commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

🤖

Summary

  • Switching back to a channel you already opened ("warm switching") got slower after the sidebar became persistent in Keep pages and channels in a persistent sidebar #234. The browser test that measures this fails when a switch takes more than 200 ms.
  • Part of the extra time came from the message list. When you switch channels, the app hands the channel page its navigation state in two steps: first with no request, then with the new one. The channel page rebuilt its "open link" and "open media" functions each time that state changed, so right after the messages appeared, every message row rendered again to receive the new functions.
  • Those two functions now look up the shown channel and navigation request when they are called. They stay the same across a switch, so message rows no longer render a second time.
  • Nothing changes on screen. Links and media open exactly as before.

Details

…navigation

Each channel switch presents its navigation request in two steps: first
without a request, then with it. ChannelsPage built openLink and
openMediaReview from the current channel and request, so they changed on
the second step. By then the warm timeline rows were already mounted, and
every memoized MessageRow rendered again for the new callbacks.

Read the shown channel and request from a ref at call time instead, as
link panel context already does. With 4x CPU throttling, the median warm
switch in channel-opening.spec falls from 193ms to 165ms in the same run
(24 samples each).

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
@loganj
loganj marked this pull request as ready for review September 25, 2026 17:09
@loganj
loganj requested review from a team, comp615 and wesbillman as code owners September 25, 2026 17:09
@loganj
loganj merged commit fff36cc into main Sep 25, 2026
19 of 21 checks passed
@loganj
loganj deleted the larry/stable-channel-callbacks branch September 25, 2026 17:13

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Post-merge review: real, proportionate optimization; no introduced correctness blocker found. Reviewed 2e24935464c06376aa2706deba01c200ba7d4aa5 against 80511fa86c2543e10447779c451ecfaf4652bff6. Already merged as fff36cc7.

  • Causality: navigation presentation is installed in a layout effect after an owner change (src/app/navigation.ts:120–166). Previously that handoff changed both callback props through the memoized timeline. In an isolated build-time probe of the existing warm-switch journey, substituting the exact base version of the sole changed file produced 83 MessageRow calls across four switches versus 48 with this patch. Callback identities changed in the base variant and stayed stable in the patched variant. This reproduction did not include #265.
  • Safety: the ref records the committed visible destination, rather than an unfinished render. Existing consumers invoke it synchronously; workspace/channel remounts and existing navigation/session authority checks preserve ownership. An isolated production-broker journey passed Chromium and WebKit: repeated channel visits, correct image/thread targets, keyboard activation and focus restoration, channel links/back, and viewer invalidation on back/forward. Three independent source-review lanes were reconciled with this runtime evidence.
  • Limits/follow-up: this proves reduced render work, not the reported 193→165 ms latency magnitude. My one-run-per-variant timings overlap; hosted before/after runners also differ. No committed regression test guards this mechanism, so add a deterministic row-render/callback regression test rather than relying only on the 200 ms ceiling. PR CI passed on rerun; Windows was skipped. Merged-main CI 36165809509 was pending at the checked snapshot. No full-suite rerun or native/live-service validation performed.

The new interaction probe initially expected root text that this viewer intentionally omits; corrected to verify a signed reply and image URL. A WebKit pointer-focus assertion also failed with the base implementation; explicit keyboard activation passes both engines. Neither was an introduced regression. No approval submitted.

cynfria pushed a commit that referenced this pull request Sep 25, 2026
…sh-pr1

* origin/main:
  Refine direct message opening (#107)
  feat(messages): report messages to community moderators (#255)
  perf(channels): stop rerendering message rows after each channel switch (#269)

Signed-off-by: Peppermint Butler <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@buzz.block.builderlab.xyz>
zrmarley added a commit that referenced this pull request Sep 25, 2026
…-image

* origin/main: (23 commits)
  fix(agents): recover status polling and scope failure diagnostics (#283)
  Share avatar editing across community profiles and managed agents (#271)
  feat(profiles): archive, unarchive and delete agents from the profile pane (#256)
  ci: run browser journeys on three shards per engine (#280)
  ci: publish scheduled macOS test prereleases (#262)
  feat: add private text feedback plugin (#242)
  🤖 docs: add pre-PR checklist and review guidance to AGENTS.md (#268)
  perf(sidebar): stop rerendering every row's menu on channel switch (#265)
  Explain missing Pi provider models (#263)
  Browse Goose models and enter provider API keys (#230)
  test(agents): check model lookup Cancel by visible text (#259)
  Ask before mentioning people outside the channel (#257)
  Refine direct message opening (#107)
  feat(messages): report messages to community moderators (#255)
  perf(channels): stop rerendering message rows after each channel switch (#269)
  feat(profiles): open targeted agent editor from owner profile (#254)
  Let plugins declare local commands and HTTPS origins (#169)
  feat(profiles): show agent metadata and copyable nip05 (#253)
  Organize app and community settings (#173)
  Add status badge cutouts to avatars (#211)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants