ollama - ✅(Solved) Fix app/ui: unnecessary JSON re-parsing and missing memo dependencies in message components [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
ollama/ollama#16004Fetched 2026-05-07 03:31:50
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
referenced ×3cross-referenced ×1labeled ×1

Root Cause

  1. Unreachable code after early returns — In ToolCallDisplay, there's a code path that checks for browser.* tool names that can never be reached because a previous branch already handles all non-browser.* names and returns.

Fix Action

Fixed

PR fix notes

PR #16008: app/ui: cleanup ToolCallDisplay and defer JSON.stringify for collapsed tools

Description (problem / solution / changelog)

  • Skip rendering collapsed tool result JSON until expanded, avoiding JSON.stringify on hidden content for every tool message.
  • Memoize JSON.parse of tool call arguments.
  • Remove redundant collapsible tool call logic from ToolCallDisplay, as it is handled by ToolRoleContent.

Fixes #16004

Changed files

  • app/ui/app/src/components/Message.tsx (modified, +34/-180)
  • app/ui/app/src/components/MessageList.tsx (modified, +8/-7)
RAW_BUFFERClick to expand / collapse

What is the issue?

Several small performance issues across the message rendering pipeline add up, especially in chats with many tool calls:

  1. Tool call arguments are re-parsed on every renderBrowserToolCallDisplay calls JSON.parse on tool call arguments during render without memoizing the result. Every re-render (e.g., during streaming) re-parses the same JSON.

  2. Collapsed tool results still run JSON.stringify — When a tool result is collapsed and invisible, the component still stringifies the raw JSON on every render. This should be deferred until the user actually expands the section.

  3. Message memo comparator is missing lastToolQuery — The custom React.memo comparator for the Message component doesn't include lastToolQuery in the comparison, which can cause missed memoization opportunities or stale renders.

  4. lastToolQueries recalculates on every streaming token — The memoized computation depends on the full messages array reference, which changes on every streamed token. Using messages.length as the dependency would prevent unnecessary recalculations since tool queries only change when new messages are added.

  5. Unreachable code after early returns — In ToolCallDisplay, there's a code path that checks for browser.* tool names that can never be reached because a previous branch already handles all non-browser.* names and returns.

  6. browserToolResult prop is untyped — The prop is typed as any in MessageList instead of using the existing BrowserToolResult type.

Relevant log output

OS

macOS

GPU

Apple

CPU

Apple

Ollama version

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING