Skip to content

perf(desktop): make warm navigation paint immediately - #6069

Open
wesbillman wants to merge 14 commits into
mainfrom
carl/loader-free-navigation
Open

perf(desktop): make warm navigation paint immediately#6069
wesbillman wants to merge 14 commits into
mainfrom
carl/loader-free-navigation

Conversation

@wesbillman

Copy link
Copy Markdown
Collaborator

Summary

  • paint warm channel and thread content from retained cache while revalidation runs behind it
  • bound retained timeline work and preserve virtualizer/provenance behavior across warm navigation
  • immediately replace the old channel pane with the destination skeleton before expensive cached rows mount
  • cancel superseded deferred navigation, including back/forward, same-channel reselects, and failed huddle routes
  • add unit, E2E, and performance coverage for warm switching and navigation lifecycle ordering

Validation

  • pre-push desktop check
  • pre-push desktop typecheck
  • pre-push desktop unit suite: 4,959 passed
  • focused navigation regression E2E coverage
  • independent review cleared exact head 448587bc2db55125bff355508b60f48ba3fdaad6

Residual risk

  • a millisecond-scale supersede window remains after route navigation begins but before commit; fully closing it requires cancellable navigation in commitNavigation
  • forced rejected-navigation behavior is code-reviewed rather than E2E-injected

wesbillman and others added 14 commits August 14, 2026 14:33
Use authoritative channel-window provenance to distinguish warm empty
channels from cold live-seeded caches. Mount each channel timeline with
its route-matched cached snapshot and revalidate the retained scrollback
extent atomically so background catch-up cannot erase the reader's anchor.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Channel-keyed timeline mounts register the child virtualizer API before the
parent layout effect runs. Do not immediately erase that registration, or
deep-link navigation can never initialize its scroll owner.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Keep the authoritative channel window alive for the same hour as its
projected message cache so revisits cannot lose loader provenance first.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Skip redundant fresh-window catch-up on warm navigation, memoize stable rows,
and narrow the retained DOM to the active viewport and tail. Strengthen the
warm-switch and scroll regression gates, including buffered live-tail recovery.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Commit the existing thread skeleton before the deferred thread-panel mount, even
when the root is already cached. Keep the expensive panel work transitional and
cover the one-frame loading state with a mutation-observer regression test.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Commit the requested sidebar selection first, then start cached channel
navigation after the browser has painted. Cancel superseded navigation work and
cover the paint ordering with an end-to-end regression test.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Track deferred sidebar and thread operations so newer navigation intent,
route changes, toggles, and unmounts cancel stale callbacks. Strengthen the
E2E coverage to prove painted feedback and latest-intent history semantics.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Subscribe the sidebar deferral to the shared navigation-intent signal so
back, forward, deep links, and every other navigation source supersede stale
channel work. Keep optimistic selection until the committed route catches up,
and cover immediate competing intents plus traversal races.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
The sidebar updates active ownership immediately during deferred navigation,
but its shared background transition visually retained the old active row while
fading in the new one. Exclude background and text colors from channel-row
transitions so selection changes atomically, and pin both singular ownership
and transition behavior at the pre-route paint boundary.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Render the destination channel skeleton as soon as sidebar intent is recorded
instead of leaving the previous channel visible while cached content renders.
Keep that skeleton through route commit and one paint, clear it safely on
superseding or failed navigation, and cover both paint boundaries in E2E.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Avoid replacing an already-selected channel with a navigation skeleton when its
sidebar item is clicked again.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Return huddle navigation promises so deferred navigation can clear its skeleton
when route commits fail, and cover reselecting the current channel while a new
channel is pending.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Return the huddle route promise through the sidebar handler so deferred
navigation can clear its destination skeleton if the route commit fails.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
@wesbillman
wesbillman requested a review from a team as a code owner August 16, 2026 18:46

@themiguelamador themiguelamador left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I found two correctness regressions in the warm-navigation path and fixed both on Complear/buzz:review/pr-6069-fix (002fd6831).

  1. The fresh-cache shortcut skipped the mandatory page-to-live catch-up when returning to a channel. The global listener only updated the projected flat cache, so a later authoritative-window projection could erase messages received while the channel was away; thread summaries could be missed as well. The subscription now always performs one background head catch-up, with a regression test that receives a message while away, returns, receives another live message, and verifies both remain.

  2. Deferred sidebar navigation read pendingChannelId from React render state. Two clicks in the same task (another channel, then the current channel) therefore let the first deferred navigation survive because the second handler still saw null. A synchronously maintained ref now owns that cancellation decision; the PR's existing reselect/cancellation E2E passes.

Validation: Desktop lint/file-size check and TypeScript typecheck pass; the complete Desktop unit suite passes (4,959 tests); the E2E build passes; all previously run focused navigation cases passed except the reproduced reselect failure, and after the fix both the reselect case and the new away-message regression pass.

Please incorporate the fix commit (or equivalent changes) before merging.

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.

2 participants