Repository navigation
perf(flow-chat): optimize long-round streaming projection and scroll rendering - #3778
Open
Raing5Days wants to merge 1 commit into
Open
Raing5Days wants to merge 1 commit into
Raing5Days wants to merge 1 commit into
Conversation
…rendering Keep settled ModelRound projections, FlowGroupData references, group indexes, search sources, and retained-byte estimates cached across streaming flushes, avoid redundant virtualizer RAF budget commits and unwatched viewport snapshot reads, and add categorized long-round benchmarks.
Raing5Days
force-pushed
the
perf/long-round-scroll-and-render
branch
from
November 6, 2026 12:51
e4130df to
e7f9534
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
Optimize Web UI
flow_chatsession scrolling and streaming projection performance during long multi-round turns (10 -> 300+ModelRounds), and add a categorized benchmark harness (src/web-ui/src/flow_chat/perf/longRoundPerfHarness*) covering the 5 frontend projection/rendering stages.Key changes:
roundGroups.ts,lifecycle.ts,groupProjection.ts,modernFlowChatStore.ts):getProjectedModelRoundGroups,getModelRoundFlowGroups,getCachedInlineFlowGroupData,flowGroupLifecycle, andmergeFlowGroupRunviaWeakMapso settledModelRounds do not recomputebuildFlowItemGroupsorcomputeExploreStatson every streaming flush.projectTurnItemsWithPrefixCache,canStartFreshFlowGroupRunAt,reconcileTurnVirtualItems,reconcileProjectedGroupsInPlace) so unchanged settled rounds before the last hard group boundary skipprojectAdjacentFlowGroupsand preserve exact===VirtualItemandFlowGroupDataobject identities (97.7%settledVirtualItemreuse,94.6%settledTimelineBlockreuse).selectors.ts,receiveFeedback.ts,useFlowChatSearch.ts):getVirtualItemFlowGroups) and incrementally reuse prefix maps inindexFlowGroups.JSON.stringify([turnId, itemId])allocations inreceiveFeedback.tswith cached per-item keys, skip completed turns incaptureFlowGroupFeedbackSnapshot, and short-circuitcollectFlowGroupReceiveFeedbackwhenprevious.activeMembers.size === 0.WeakMap<VirtualItem, ...>.resourceBudget.ts,EventHandlerModule.ts):ModelRounds and completed-round prefix sums per turn inestimateRetainedBytes, turning the 500ms budget walk on active turns fromO(rounds)toO(1)incremental tail evaluation.missing_state_machinedata events for unloaded internal background sessions (e.g.MemoryPhase2) instead of logging warnings and triggeringrequestRuntimeProjectionRepairhundreds of times per second.useFlowChatVirtualizer.ts,VirtualMessageList.tsx):MAX_SYNCHRONOUS_VIRTUALIZER_COMMITS.viewportSnapshotRAF and full DOM geometry reads whenonViewportSnapshotis not provided, and lazily samplereadFlowChatViewportGeometryin nativescrollhandlers.Type and Areas
Type:
Performance / refactor / test
Areas:
Web UI (
src/web-ui/src/flow_chat,src/web-ui/src/shared/utils/resourceBudget.ts)Motivation / Impact
During long multi-round agent turns (100–300+ rounds), every 32ms streaming flush previously re-projected all completed rounds in the active turn and allocated fresh
VirtualItem/FlowGroupDatareferences. That invalidated downstreamWeakMapcaches inConversationDocumentProjectionandReact.memoonVirtualItemRenderer, causingO(rounds)main-thread work per flush and unnecessary settled-row re-renders.Measured benchmark improvements (
src/flow_chat/perf/longRoundPerfHarness.test.tsx, 10 -> 300 rounds, 20 flushes):bench:store-projection):111.79 ms -> 7.82 ms(~14xfaster), settledVirtualItemreference reuse6.8% -> 97.7%.bench:timeline-document):17.16 ms -> 3.12 ms(5.5xfaster), settledTimelineBlockreference reuse62.8% -> 94.6%.bench:group-state-search):14.12 ms -> 3.74 ms(3.8xfaster).bench:budget-persistence):estimateRetainedBytesper-call at 300 rounds1.56 ms -> 0.01 ms(100x+faster).bench:react-streaming, 120 rounds, 10 tail chunks):VirtualMessageListcommits23 -> 14, wasted settled-row renders805 -> 2.bench:e2e-pipeline): Total 5-stage pipeline time139.67 ms -> 12.38 ms(avg0.39~0.62 ms/flush).Verification
Automated checks run locally (all passed):
pnpm --dir src/web-ui exec tsc --noEmitpnpm --dir src/web-ui exec eslint src/flow_chat/grouping/roundGroups.ts src/flow_chat/grouping/lifecycle.ts src/flow_chat/grouping/groupProjection.ts src/flow_chat/grouping/selectors.ts src/flow_chat/grouping/receiveFeedback.ts src/flow_chat/store/modernFlowChatStore.ts src/flow_chat/components/modern/useFlowChatSearch.ts src/flow_chat/components/modern/useFlowChatVirtualizer.ts src/flow_chat/components/modern/VirtualMessageList.tsx src/shared/utils/resourceBudget.ts src/flow_chat/services/flow-chat-manager/EventHandlerModule.ts src/flow_chat/perf/longRoundPerfHarness.ts src/flow_chat/perf/longRoundPerfHarness.test.tsxpnpm --dir src/web-ui exec vitest run src/flow_chat/perf/longRoundPerfHarness.test.tsxpnpm --dir src/web-ui exec vitest run src/flow_chat/store/modernFlowChatStore.test.ts src/flow_chat/grouping/activityGrouping.test.ts src/flow_chat/grouping/receiveFeedback.test.ts src/flow_chat/timeline/document.test.ts src/shared/utils/resourceBudget.test.ts src/flow_chat/services/flow-chat-manager/EventHandlerModule.test.ts src/flow_chat/components/modern/useFlowChatSearch.test.tspnpm --dir src/web-ui exec vitest run src/flow_chat/components/modern/useFlowChatVirtualizer.test.ts src/flow_chat/components/modern/useFlowChatVirtualizer.cascade.test.tsx src/flow_chat/components/modern/useFlowChatVirtualizer.measurement.test.tsx src/flow_chat/components/modern/useFlowChatVirtualizer.follow.test.tsx src/flow_chat/components/modern/useFlowChatVirtualizer.initial-window.test.tsx src/flow_chat/components/modern/useFlowChatVirtualizer.aim.test.tsx src/flow_chat/components/modern/useFlowChatViewportAnchor.test.tsx src/flow_chat/components/modern/useFlowChatViewportOwner.test.tsx src/flow_chat/components/modern/useFlowChatFollowOutput.test.ts src/flow_chat/components/modern/useFlowChatFollowOutput.hook.test.tsx src/flow_chat/components/modern/useFlowChatFollowOutput.test.tsx src/flow_chat/components/modern/useFlowChatLeadingExtent.test.tsx src/flow_chat/components/modern/VirtualMessageList.session-boundary.test.tsx src/flow_chat/components/modern/VirtualMessageList.resize.test.tsx src/flow_chat/components/modern/VirtualMessageList.history-prepend.test.tsx src/flow_chat/components/modern/VirtualMessageList.timeline-prepend.test.tsx src/flow_chat/components/modern/VirtualMessageList.edgeFade.test.ts src/flow_chat/components/modern/VirtualMessageList.layout.test.ts src/flow_chat/components/modern/modelRoundItemMemo.test.tspnpm run check:repo-hygienenode scripts/check-git-object-sizes.mjs --base origin/main --head HEADRemote scenarios & manual checks:
FLOWCHAT_VERIFICATION.mdremain pending human confirmation.Reviewer Notes
Checklist