1jehuang / 1jehuang/jcode

TUI input and scrolling degrade in long sessions due to render-path work and mixed terminal readers

Open
#540 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no bug priority: high triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Summary

Terminal interactivity can degrade substantially in longer Jcode sessions. Typing becomes delayed, mouse-wheel scrolling causes excessive redraw work, and fragmented mouse reports can appear as text in the composer.

I reproduced this on macOS using a real PTY. The underlying problems are in shared Jcode TUI code rather than macOS-specific application code.

Symptoms

• Input latency grows as the conversation becomes longer.
• Scrolling can cause large bursts of terminal output and high CPU usage.
• Input may fall back to redraw-tick latency instead of waking immediately.
• Mouse-wheel bursts can trigger a full repaint for every packet.
• Raw SGR mouse fragments such as [<65;50;24M can leak into the composer.

Reproduction evidence

On the broken build, a real PTY input probe missed 32 of 40 keystrokes and had approximately 169 ms median latency.

With the proposed fix:

• 40 of 40 keystrokes were delivered.
• Median latency was 0.254 ms.
• P95 latency was 0.438 ms.
• Under eight CPU burners, all 40 keystrokes were still delivered.
• A 96-byte burst completed in 0.635 ms with only three draws.

The severity depends on terminal timing and conversation size, but the problematic code paths are deterministic.

Root causes

The investigation found three independent causes:

  1. Cache-hit telemetry performed transcript-linear byte estimation during rendering. This turns a nominal cache hit into work proportional to conversation size.

  2. Memory sidecar discovery performed credential and model resolution on the render path.

  3. Jcode mixed Crossterm’s asynchronous EventStream with synchronous poll and read calls. This violates Crossterm’s single-reader requirement and can split terminal packets. Removing the synchronous drain without replacing its coalescing also caused one full repaint per queued wheel or keyboard event.

The input reader also needed to preserve partially consumed Escape sequences across cancellation inside Tokio select calls. Otherwise a redraw or bus event could cancel the read and lose part of the terminal packet.

Proposed fix

I prepared an isolated branch with three commits:

https://github.com/apierron/jcode/tree/fix/tui-terminal-interactivity-lag

Comparison against upstream:

https://github.com/1jehuang/jcode/compare/master…apierron:fix/tui-terminal-interactivity-lag

Commits:

• be511853: Keep cache-hit metrics constant-time.
• f057724a: Move sidecar discovery off the render path.
• 8c530734: Use one bounded, cancellation-safe terminal reader and coalesce ready input before redrawing.

The branch changes only TUI code, adds no dependencies, and separates the three root causes into independent commits.

Validation

• Eight terminal-reader tests pass, covering ordering, cancellation, Escape deadlines, bounded lossless backpressure, prompt wakeups, coalescing, and task shutdown.
• Three focused render-path and cache tests pass.
• Formatting, Cargo check, and the Jcode TUI build pass.
• The changed files match the previously runtime-tested build.
• An independent review found no blocking correctness or scope issues.
• The full TUI suite still has existing environment and global-state failures, but the fix branch introduces no branch-only failures compared with the same suite on upstream master.

Platform scope

This was reproduced on macOS, but most of the problem is not macOS-specific:

• Transcript-linear cache work is platform-independent.
• Blocking sidecar discovery during rendering is platform-independent.
• The mixed-reader violation exists in shared, non-platform-gated Jcode code.
• Fragmented SGR mouse reports are a Unix and Crossterm behavior, so the raw mouse-text symptom is most likely on macOS and Linux.
• Terminal implementation and OS scheduling can change how severe the lag appears.

I have not run the final branch through equivalent real-terminal measurements on Linux or Windows, so identical reproduction there is not yet confirmed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the three commits on the linked fix/tui-terminal-interactivity-lag branch, then run the eight terminal-reader tests and the focused render-path and cache tests described in the issue. Done means preserving prompt responsiveness and input ordering, coalescing redraws, keeping render-path work bounded, and passing formatting, Cargo check, and the TUI build.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, performance, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.