diff options
| author | Shoubhit Dash <[email protected]> | 2026-03-11 18:19:17 +0530 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-11 18:19:17 +0530 |
| commit | 7291e282738a3745330e20180371bd7c6fb11e5b (patch) | |
| tree | 95f1d0be625044014b09e97e2b3a5fe35cc55589 | |
| parent | db57fe6193322941f71b11c5b0ccb8f03d085804 (diff) | |
| download | opencode-7291e282738a3745330e20180371bd7c6fb11e5b.tar.gz opencode-7291e282738a3745330e20180371bd7c6fb11e5b.zip | |
perf(app): trim session render work (#16987)
| -rw-r--r-- | packages/app/src/pages/session/message-timeline.tsx | 1 | ||||
| -rw-r--r-- | packages/ui/src/components/message-part.tsx | 36 |
2 files changed, 23 insertions, 14 deletions
diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index 6463e7cbb..223539092 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -764,6 +764,7 @@ export function MessageTimeline(props: { "min-w-0 w-full max-w-full": true, "md:max-w-200 2xl:max-w-[1000px]": props.centered, }} + style={{ "content-visibility": "auto", "contain-intrinsic-size": "auto 500px" }} > <Show when={commentCount() > 0}> <div class="w-full px-4 md:px-5 pb-2"> diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index afe4109e1..65b6229d6 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -437,8 +437,8 @@ function groupParts(parts: { messageID: string; part: PartType }[]) { return result } -function partByID(parts: readonly PartType[], partID: string) { - return parts.find((part) => part.id === partID) +function index<T extends { id: string }>(items: readonly T[]) { + return new Map(items.map((item) => [item.id, item] as const)) } function renderable(part: PartType, showReasoningSummaries = true) { @@ -474,6 +474,13 @@ export function AssistantParts(props: { const data = useData() const emptyParts: PartType[] = [] const emptyTools: ToolPart[] = [] + const msgs = createMemo(() => index(props.messages)) + const part = createMemo( + () => + new Map( + props.messages.map((message) => [message.id, index(list(data.store.part?.[message.id], emptyParts))] as const), + ), + ) const grouped = createMemo( () => @@ -507,7 +514,7 @@ export function AssistantParts(props: { const entry = entryAccessor() if (entry.type !== "context") return emptyTools return entry.refs - .map((ref) => partByID(list(data.store.part?.[ref.messageID], emptyParts), ref.partID)) + .map((ref) => part().get(ref.messageID)?.get(ref.partID)) .filter((part): part is ToolPart => !!part && isContextGroupTool(part)) }, emptyTools, @@ -527,23 +534,23 @@ export function AssistantParts(props: { const message = createMemo(() => { const entry = entryAccessor() if (entry.type !== "part") return - return props.messages.find((item) => item.id === entry.ref.messageID) + return msgs().get(entry.ref.messageID) }) - const part = createMemo(() => { + const item = createMemo(() => { const entry = entryAccessor() if (entry.type !== "part") return - return partByID(list(data.store.part?.[entry.ref.messageID], emptyParts), entry.ref.partID) + return part().get(entry.ref.messageID)?.get(entry.ref.partID) }) return ( <Show when={message()}> - <Show when={part()}> + <Show when={item()}> <Part - part={part()!} + part={item()!} message={message()!} showAssistantCopyPartID={props.showAssistantCopyPartID} turnDurationMs={props.turnDurationMs} - defaultOpen={partDefaultOpen(part()!, props.shellToolDefaultOpen, props.editToolDefaultOpen)} + defaultOpen={partDefaultOpen(item()!, props.shellToolDefaultOpen, props.editToolDefaultOpen)} /> </Show> </Show> @@ -695,6 +702,7 @@ export function AssistantMessageDisplay(props: { showReasoningSummaries?: boolean }) { const emptyTools: ToolPart[] = [] + const part = createMemo(() => index(props.parts)) const grouped = createMemo( () => groupParts( @@ -723,7 +731,7 @@ export function AssistantMessageDisplay(props: { const entry = entryAccessor() if (entry.type !== "context") return emptyTools return entry.refs - .map((ref) => partByID(props.parts, ref.partID)) + .map((ref) => part().get(ref.partID)) .filter((part): part is ToolPart => !!part && isContextGroupTool(part)) }, emptyTools, @@ -739,16 +747,16 @@ export function AssistantMessageDisplay(props: { </Match> <Match when={entryType() === "part"}> {(() => { - const part = createMemo(() => { + const item = createMemo(() => { const entry = entryAccessor() if (entry.type !== "part") return - return partByID(props.parts, entry.ref.partID) + return part().get(entry.ref.partID) }) return ( - <Show when={part()}> + <Show when={item()}> <Part - part={part()!} + part={item()!} message={props.message} showAssistantCopyPartID={props.showAssistantCopyPartID} /> |
