perf(flow-chat): reduce session opening latency - #3183
Merged
Merged
Conversation
Keep the changing edge-mask stop local to the scroller so scroll-edge updates do not invalidate every message row. Runtime opening traces reduced the follow-up style stall from 562.3ms to 3.6ms.
Keep the opening transcript measurable while preventing hidden message controls from receiving pointer, scroll, keyboard, or programmatic focus events. Replace whole-tree inert and visibility transitions with a local shield, focus guards, aria-hidden, and opacity; retain guard nodes through reveal to avoid repeated style invalidation. Add focused boundary contracts and document the measured reveal behavior.
Seed the initial virtual window from estimated row heights to avoid mounting head rows before following the tail. Preserve history restoration and defer the seed until initial hydration has items. A same-session desktop trace reduced rowRef time from 377.3ms to 4.2ms and advanced the post-reveal probe from 1540.3ms to 806.7ms. These are single-trace timings, not paint guarantees. Validation: 130 focused tests, check:web, focused ESLint, and diff checks passed. Remote scenarios were not exercised.
Reconcile the existing follow target after measured row sizes enter the virtualizer cache, then publish the actual offset before the next window is selected. Prevent delayed scroll-end samples from restoring an older offset and causing overscan rows to unmount and remount. Limit reconciliation to active, unsuspended opening transcripts owned by follow-output. Preserve user takeover and historical reading rules. A same-session desktop retest reduced row cleanup calls from five to zero and advanced post-reveal sampling from 786.8ms to 596.4ms. These are single-trace observations, not paint timing or remote validation. Validation: 57 focused tests rerun successfully; staged diff checked. The implementation previously passed 187 related tests, check:web, and focused ESLint. Temporary diagnostics remain outside this commit.
Limit the 32 reveal highlight rules to text parents with active arrivals. Keep markers stable across animation frames and release empty shared highlight buckets without interrupting other renderer owners. Preserve the 160 ms fade and settle history, replacements, and reduced motion. A complete local desktop trace reduced pre-reveal style work from 451.5 ms to 172.4 ms. The two row-batch style updates fell from 128.3/223.3 ms to 45.4/61.4 ms; overall opening latency remains variable. Validation: 10 reveal lifecycle tests and check:web passed. Motion audit completed. Remote scenarios were not exercised.
Publish the actual scrollTop readback after an opening follow correction so the virtualizer can expand its range before the delayed native scroll event. Keep the update on the existing observer channel without flushSync, preserve viewport ownership and suspension guards, and cover clamping, stale events, and takeover behavior with focused tests.\n\nA desktop trace showed range expansion about 65 ms earlier and reveal about 15 ms earlier; these are diagnostic single-trace results rather than fixed runtime guarantees.
wsp1911
force-pushed
the
flowchat-perf-pr
branch
from
September 21, 2026 16:27
babbe9a to
f427d77
Compare
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.
Summary
Improve FlowChat session opening performance by reducing initial transcript work and
synchronizing viewport state earlier during opening.
Type and Areas
Type: regression fix, UI/UX, test
Areas: web UI, FlowChat, Markdown rendering
Motivation / Impact
Opening a session previously rendered and measured the transcript from the head
before settling near the tail, causing unnecessary layout and virtualization work.
This PR:
without a synchronous React flush.
The changes reduce unnecessary opening work and improve the time before the first
visible transcript content stabilizes. In a desktop measurement, virtual range
expansion moved approximately 65 ms earlier and reveal completion approximately
15 ms earlier. These figures are sample measurements rather than runtime guarantees.
Verification
pnpm --dir src/web-ui exec vitest run src/flow_chat/components/modern/useFlowChatFollowOutput.test.tsx src/flow_chat/components/modern/useFlowChatVirtualizer.initial-window.test.tsx src/flow_chat/components/modern/useFlowChatVirtualizer.measurement.test.tsx src/flow_chat/components/modern/VirtualMessageList.session-boundary.test.tsx src/flow_chat/components/modern/FlowChatOpeningBoundary.test.tsxpnpm run check:webgit diff --checkReviewer Notes
The viewport offset handoff uses the existing TanStack virtualizer observer
channel and intentionally avoids
flushSync. Opening interaction remainssuppressed until the transcript reaches its settled state, then focus and pointer
behavior return to the normal path.
Checklist