fix(app): eliminate session switch latency — deferRender, Suspense flash, instant rendering#31395
Open
BYK wants to merge 1 commit into
Open
fix(app): eliminate session switch latency — deferRender, Suspense flash, instant rendering#31395BYK wants to merge 1 commit into
BYK wants to merge 1 commit into
Conversation
…ense flash, and instant rendering
Remove three compounding session-switch responsiveness issues:
1. Remove deferRender mechanism — eliminates the rAF + setTimeout chain in
session.tsx that blanked the review panel and gated the composer on every
session switch, causing a ~170ms gap where UI was invisible.
2. Remove sessionSync() JSX read — the createResource was read in JSX
({sessionSync() ?? ""}), triggering the nearest Suspense boundary (the
app-level splash screen) on every session switch while the sync Promise
was pending. The resource returns void so the read was a no-op.
3. Widen messagesReady gate — accept when the session exists in the session
list even before messages have loaded. This eliminates the blank screen
on session switch; the composer and timeline render immediately with
cached session data.
4. Remove 140ms artificial setTimeout in session-composer-region — the
composer now re-shows after a single rAF yield (~16ms).
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR removes deferred rendering and artificial readiness delays in the session UI, aiming to render sooner (including when cached session data exists) and simplify render timing logic.
Changes:
- Remove the
deferRendermechanism and stop gating major UI sections on it. - Make
messagesReadytrue when either messages are loaded or the session is already present in the local session list. - Remove the extra timeout-based delay before marking the composer region as ready.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/app/src/pages/session/composer/session-composer-region.tsx | Removes the setTimeout delay in the composer readiness effect, making readiness flip on the next animation frame. |
| packages/app/src/pages/session.tsx | Eliminates deferRender, adjusts readiness logic to allow cached-session rendering, and removes a render-time sessionSync() invocation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
101
to
113
| createEffect(() => { | ||
| route.sessionKey() | ||
| const ready = props.ready | ||
| const delay = 140 | ||
|
|
||
| clear() | ||
| setStore("ready", false) | ||
| if (!ready) return | ||
|
|
||
| frame = requestAnimationFrame(() => { | ||
| frame = undefined | ||
| timer = window.setTimeout(() => { | ||
| setStore("ready", true) | ||
| timer = undefined | ||
| }, delay) | ||
| setStore("ready", true) | ||
| }) | ||
| }) |
Comment on lines
320
to
325
| const messagesReady = createMemo(() => { | ||
| const id = params.id | ||
| if (!id) return true | ||
| return sync.data.message[id] !== undefined | ||
| // Ready when messages are loaded OR session exists in the list (render immediately with cached data) | ||
| return sync.data.message[id] !== undefined || sync.session.get(id) !== undefined | ||
| }) |
Comment on lines
1699
to
1700
| <div class="relative size-full overflow-hidden flex flex-col"> | ||
| {sessionSync() ?? ""} | ||
| <SessionHeader /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #19793
Type of change
What does this PR do?
Fixes three compounding session-switch responsiveness issues:
Remove deferRender mechanism — eliminates the one-frame blank + 140ms
setTimeoutinsession-composer-regionthat caused a ~170ms gap where the composer was invisible on every session switch. The composer now re-shows after a single rAF yield (~16ms).Remove sessionSync JSX read —
{sessionSync() ?? ""}was read in JSX, triggering the app-level<Suspense>boundary (splash screen) on every session switch. Since the resource returns void, the read is removed entirely — the fetcher still runs reactively from its source signal.Widen messagesReady gate — allow rendering when the session exists in the session list, even before messages have loaded. This eliminates the blank screen on session switch; the composer and timeline render immediately with cached session data.
Remove 140ms artificial setTimeout in session-composer-region — the composer now re-shows after a single rAF yield (~16ms).
How did you verify your code works?
Tested locally by rapidly switching between sessions in the web UI. Verified no blank flashes, no splash screen flicker, and the composer appears instantly. Messages load in the background with a spinner shown during loading.
Screenshots / recordings
N/A — performance/latency improvement.
Checklist