Resizing takes long when sessions are large #323

Closed
opened 2026-02-16 17:26:13 -05:00 by yindo · 11 comments
Owner

Originally created by @Schniz on GitHub (Jun 27, 2025).

Originally assigned to: @thdxr on GitHub.

It also affects re-opening sessions. So I guess it's related to a full re-render. makes sense given that there's a lot happening in a long session.

Originally created by @Schniz on GitHub (Jun 27, 2025). Originally assigned to: @thdxr on GitHub. It also affects re-opening sessions. So I guess it's related to a full re-render. makes sense given that there's a lot happening in a long session.
yindo closed this issue 2026-02-16 17:26:13 -05:00
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

I want to try and tackle it by spawning goroutines when possible. But wanted to make sure it's reported so maybe someone else fixes it before me

@Schniz commented on GitHub (Jun 27, 2025): I want to try and tackle it by spawning goroutines when possible. But wanted to make sure it's reported so maybe someone else fixes it before me
Author
Owner

@fussy0064 commented on GitHub (Jun 27, 2025):

🙆😒

@fussy0064 commented on GitHub (Jun 27, 2025): **🙆😒**
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

added some debug logs, it's clearly message rendering:

time=2025-06-27T10:49:28.769+03:00 level=INFO msg="rendering messages took" ms=11914 messagesCount=49
diff for the log
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index da45545..2b0d770 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -16,6 +16,8 @@ import (
 	"github.com/sst/opencode/internal/styles"
 	"github.com/sst/opencode/internal/theme"
 	"github.com/sst/opencode/pkg/client"
+
+	"log/slog"
 )
 
 type MessagesComponent interface {
@@ -124,7 +126,17 @@ func (m *messagesComponent) renderView() {
 	t := theme.CurrentTheme()
 	blocks := make([]string, 0)
 	previousBlockType := none
-	for _, message := range m.app.Messages {
+	renderTime := time.Now()
+	defer func() {
+		slog.Info("rendering messages took", "ms", time.Since(renderTime).Milliseconds(), "messagesCount", len(m.app.Messages))
+	}()
+	for i, message := range m.app.Messages {
+		func() {
+			startAt := time.Now()
+			defer func() {
+				slog.Info("render message", "messageIndex", i, "timeTaken", time.Since(startAt).Milliseconds())
+			}()
+
 			var content string
 			var cached bool
 			lastToolIndex := 0
@@ -237,6 +249,7 @@ func (m *messagesComponent) renderView() {
 					previousBlockType = errorBlock
 				}
 			}
+		}()
 	}
 
 	centered := []string{}
@Schniz commented on GitHub (Jun 27, 2025): added some debug logs, it's clearly message rendering: ```log time=2025-06-27T10:49:28.769+03:00 level=INFO msg="rendering messages took" ms=11914 messagesCount=49 ``` <details> <summary>diff for the log</summary> ```diff diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go index da45545..2b0d770 100644 --- a/packages/tui/internal/components/chat/messages.go +++ b/packages/tui/internal/components/chat/messages.go @@ -16,6 +16,8 @@ import ( "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" "github.com/sst/opencode/pkg/client" + + "log/slog" ) type MessagesComponent interface { @@ -124,7 +126,17 @@ func (m *messagesComponent) renderView() { t := theme.CurrentTheme() blocks := make([]string, 0) previousBlockType := none - for _, message := range m.app.Messages { + renderTime := time.Now() + defer func() { + slog.Info("rendering messages took", "ms", time.Since(renderTime).Milliseconds(), "messagesCount", len(m.app.Messages)) + }() + for i, message := range m.app.Messages { + func() { + startAt := time.Now() + defer func() { + slog.Info("render message", "messageIndex", i, "timeTaken", time.Since(startAt).Milliseconds()) + }() + var content string var cached bool lastToolIndex := 0 @@ -237,6 +249,7 @@ func (m *messagesComponent) renderView() { previousBlockType = errorBlock } } + }() } centered := []string{} ``` </details>
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

this is mostly tool call rendering

@Schniz commented on GitHub (Jun 27, 2025): this is mostly tool call rendering
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

specifically edit tools, i guess because of syntax highlight and diffing.

Part Type / Tool Type Count Min Max Mean Std Dev Notes
step-start 400 0 0 0 0 All zero, just a marker
text 400 0 21 0.77 1.98 Mostly zero, rare spikes
tool-invocation/read 100 0 1 0.98 0.14 Almost always 1, very consistent
tool-invocation/grep 16 0 0 0 0 All zero, possibly not used or very fast
tool-invocation/todowrite 56 0 1 0.32 0.47 Mostly zero, some ones
tool-invocation/edit 160 0 470 61.2 87.6 High mean and stddev, many large outliers
tool-invocation/bash 140 0 15 2.23 2.36 Most are low, but some spikes (up to 15)
@Schniz commented on GitHub (Jun 27, 2025): specifically edit tools, i guess because of syntax highlight and diffing. | Part Type / Tool Type | Count | Min | Max | Mean | Std Dev | Notes | |------------------------------|-------|-----|-----|--------|---------|--------------------------------------------| | **step-start** | 400 | 0 | 0 | 0 | 0 | All zero, just a marker | | **text** | 400 | 0 | 21 | 0.77 | 1.98 | Mostly zero, rare spikes | | **tool-invocation/read** | 100 | 0 | 1 | 0.98 | 0.14 | Almost always 1, very consistent | | **tool-invocation/grep** | 16 | 0 | 0 | 0 | 0 | All zero, possibly not used or very fast | | **tool-invocation/todowrite**| 56 | 0 | 1 | 0.32 | 0.47 | Mostly zero, some ones | | **tool-invocation/edit** | 160 | 0 | 470 | 61.2 | 87.6 | High mean and stddev, many large outliers | | **tool-invocation/bash** | 140 | 0 | 15 | 2.23 | 2.36 | Most are low, but some spikes (up to 15) |
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

^ ai generated table obviously

@Schniz commented on GitHub (Jun 27, 2025): ^ ai generated table obviously
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

okay no time left today, but i guess we should focus on edit. i want to try to see what's making it slow. probably syntax highlight or diffing. if it's syntax highlighting, maybe we can do it in the background or skip syntax highlighting completely if the message is not in the viewport. or if we can't know that, do it in the background for every message.

@Schniz commented on GitHub (Jun 27, 2025): okay no time left today, but i guess we should focus on `edit`. i want to try to see what's making it slow. probably syntax highlight or diffing. if it's syntax highlighting, maybe we can do it in the background or skip syntax highlighting completely if the message is not in the viewport. or if we can't know that, do it in the background for every message.
Author
Owner

@adamdotdevin commented on GitHub (Jun 27, 2025):

okay no time left today, but i guess we should focus on edit. i want to try to see what's making it slow. probably syntax highlight or diffing. if it's syntax highlighting, maybe we can do it in the background or skip syntax highlighting completely if the message is not in the viewport. or if we can't know that, do it in the background for every message.

with so much new work to take on i kept punting this, it'd be huge if you could pull on this thread!

@adamdotdevin commented on GitHub (Jun 27, 2025): > okay no time left today, but i guess we should focus on `edit`. i want to try to see what's making it slow. probably syntax highlight or diffing. if it's syntax highlighting, maybe we can do it in the background or skip syntax highlighting completely if the message is not in the viewport. or if we can't know that, do it in the background for every message. with so much new work to take on i kept punting this, it'd be huge if you could pull on this thread!
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

Good news: spawning goroutines make my session render in 2s instead of 12s. I'll try to introduce more concurrency.

@Schniz commented on GitHub (Jun 27, 2025): Good news: spawning goroutines make my session render in 2s instead of 12s. I'll try to introduce more concurrency.
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

That being said I'm not happy because that's wasting cpu on stuff we don't need to, and feels weird to spawn recklessly without some concurrency control. I believe caching could also help. But that's the easiest and fastest path I can think of

@Schniz commented on GitHub (Jun 27, 2025): That being said I'm not happy because that's wasting cpu on stuff we don't need to, and feels weird to spawn recklessly without some concurrency control. I believe caching could also help. But that's the easiest and fastest path I can think of
Author
Owner

@Schniz commented on GitHub (Jun 27, 2025):

Considering adding opentelemetry to allow to debug things like that in the future. Telling people to run an Otel collector and share the trace could be very beneficial

@Schniz commented on GitHub (Jun 27, 2025): Considering adding opentelemetry to allow to debug things like that in the future. Telling people to run an Otel collector and share the trace could be very beneficial
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#323