on main help sign in
fix(ui): optimize assistant message rendering to improve performance (#2258)

This commit attempts to fix an issue where the rendering of assistant messages in the chat UI can become significantly degraded in performance, especially for long messages. The root cause of the performance degradation was identified as the use of lipgloss.Render for applying styles to the message content, which involves wrapping logic that can be expensive for long messages.

commit46ebd20b63d8e5265e14393821ce747e8ce44ff3 authorAyman Bagabas <ayman.bagabas@gmail.com> dateThu 19 Feb 2026, 17:00 (8 months ago) parent9862d3a
1 file changed+16−4
internal/ui/chat/assistant.go+16−4
internal/ui/chat/assistant.go+16−4
@@ -107,11 +107,23 @@ func (a *AssistantMessageItem) RawRender(width int) string {
107107
108108// Render implements MessageItem.
109109func (a *AssistantMessageItem) Render(width int) string {
110− style := a.sty.Chat.Message.AssistantBlurred
111− if a.focused {
112− style = a.sty.Chat.Message.AssistantFocused
110+ // XXX: Here, we're manually applying the focused/blurred styles because
111+ // using lipgloss.Render can degrade performance for long messages due to
112+ // it's wrapping logic.
113+ // We already know that the content is wrapped to the correct width in
114+ // RawRender, so we can just apply the styles directly to each line.
115+ focused := a.sty.Chat.Message.AssistantFocused.Render()
116+ blurred := a.sty.Chat.Message.AssistantBlurred.Render()
117+ rendered := a.RawRender(width)
118+ lines := strings.Split(rendered, "\n")
119+ for i, line := range lines {
120+ if a.focused {
121+ lines[i] = focused + line
122+ } else {
123+ lines[i] = blurred + line
124+ }
113125 }
114− return style.Render(a.RawRender(width))
126+ return strings.Join(lines, "\n")
115127}
116128
117129// renderMessageContent renders the message content including thinking, main content, and finish reason.