perf: reduce input tarpitting and speed up large-display rendering

Input tarpitting fixes:
- terminal.ts: batch stdin writes with 10ms coalescing window (flushes
  immediately for large payloads like paste), replacing per-keystroke
  WebSocket messages with fewer, larger frames
- server.go: replace per-message time.After() with a reusable timer to
  eliminate GC pressure from repeated key input
- server.go: coalesce queued stdin writes (up to 4KB) into a single PTY
  write to reduce syscall overhead

Screenshot/rendering pipeline optimizations:
- tracker.go: stop forcing empty cells to space; let exporters decide
  what to render, drastically reducing work for mostly-blank terminals
- tracker.go: use clear() for dirty map instead of delete-in-loop
- svg_exporter.go: skip visually empty cells (blank glyph, default BG,
  no reverse/underline); still render background rects for colored or
  reverse-video cells
- png_exporter.go: add color parsing cache to avoid redundant hex
  parsing per cell; add empty cell fast-path; short-circuit blend math
  for coverage 0 and 255

Dashboard thumbnail concurrency:
- server.go: replace single-flight screenshot fetching with limited
  parallelism (2-4 concurrent requests based on hardwareConcurrency)
  so large dashboards with many tiles update faster

Also fixes typo in dashboard JS (tetagBySlug -> etagBySlug) that
silently broke ETag caching for screenshot refreshes.

Bumps version to 1.3.32.
This commit is contained in:
GitHub Copilot
2026-02-26 19:56:58 +00:00
parent 2d9cb7f062
commit 82ccfeb6a9
7 changed files with 252 additions and 84 deletions
+1 -6
View File
@@ -74,9 +74,7 @@ func (t *Tracker) Feed(data []byte) error {
if len(t.screen.Dirty) > 0 {
t.changeCounter++
// Clear dirty set so subsequent feeds detect new changes
for k := range t.screen.Dirty {
delete(t.screen.Dirty, k)
}
clear(t.screen.Dirty)
}
return nil
}
@@ -108,9 +106,6 @@ func (t *Tracker) Snapshot() Snapshot {
for col := 0; col < t.screen.Columns; col++ {
raw := t.screen.Buffer[row][col]
data := raw.Data
if data == "" {
data = " "
}
line[col] = Cell{
Data: data,
FG: colorToString(raw.Attr.Fg),