[BUG] Fullscreen: full-viewport repaints degrade whole-window latency in the VS Code integrated terminal (root-caused; scrolling not required)
Update — root-caused, and two corrections to this report. The cause is xterm.jsscreenReaderMode(driven by VS Code'seditor.accessibilitySupport) doing a forced synchronous reflow per terminal row per render, amplified by fullscreen's full-viewport repaint. Details in this comment. Two claims in the original report below are retracted and struck through: that scrolling is required to trigger it, and that sending a message reliably clears it. Corrections in this comment. Everything else stands.
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
In fullscreen rendering ("tui": "fullscreen"), a sustained stream of repaints progressively degrades the entire UI. Scrolling up through a long conversation with the mouse wheel is the fastest way to trigger it, but it is not required — see below. After enough repaint volume, a single wheel notch takes 1–3 seconds to register. The degradation then persists after all input stops — it is not a transient scroll-feel problem.
While degraded:
- Text selection inside Claude Code lags by the same 1–3 seconds.
- Hovering VS Code's own terminal buttons (split, close) lags identically, so the host editor's UI is affected too.
- ~~Sending a message instantly restores full responsiveness, every time. This is the most reliable signal in the whole repro.~~ Retracted — this is not reliable. On repeated observation it sometimes did nothing.
Scrolling is not required. It also degrades with no mouse input at all, during ordinary streaming output where the view auto-scrolls on its own. The animated spinner glyph makes it obvious — its frame rate visibly drops and stutters while nothing is being scrolled, selected, or clicked. The common factor is repaint volume, not scroll input.
Continuous scrolling in one direction is enough to trigger it quickly. Scrolling up and down is not required — I originally reported it that way only because it was a convenient way to stay inside the scrollback.
This is distinct from #56546 and #80033, which describe jank during scrolling. Here the lag outlives the input and degrades unrelated interactions.
Steps to Reproduce
"tui": "fullscreen"in settings.- Open Claude Code in the VS Code integrated terminal.
- Build up a conversation long enough to scroll through (a few screens is enough; a longer one degrades faster).
- Scroll up continuously with the mouse wheel.
- After enough scrolling, stop. Latency per notch is now 1–3 seconds and stays there.
- Try selecting text — same lag. Hover a VS Code terminal button — same lag.
- ~~Send any message. Responsiveness returns immediately.~~ Retracted, see above.
Alternative trigger with no mouse input: leave a long-running request streaming output in a tall terminal and watch the spinner glyph stutter.
Environment
- Claude Code: 2.1.224 (native installer)
- VS Code: 1.132.0 (also reproduced on 1.127.0)
- OS: Windows 11 (10.0.26200)
- Shell: PowerShell 7
- GPU: NVIDIA RTX 4080 SUPER, driver 32.0.16.1088, 3840×2160 @ 143 Hz, DPR 2
What I ruled out
Each of these was tested individually; the bug reproduces unchanged in every case.
| Eliminated | How |
|---|---|
| Mouse-wheel acceleration | "wheelScrollAccelerationEnabled": false, restarted |
| ~~VS Code GPU acceleration~~ | ~~"terminal.integrated.gpuAcceleration": "off", new terminal (DOM renderer confirmed active by appearance change)~~ — this test was not conclusive. The real cost is DOM layout, which neither renderer avoids. See the root-cause comment |
| VS Code version | Reproduces on both 1.127.0 and 1.132.0 |
| Third-party VS Code customization | All injected CSS/JS extensions disabled and confirmed cleared |
| CPU / memory exhaustion in the CLI | Sampled claude.exe at 5 Hz during the degraded state: ~0% CPU with brief spikes, working set flat, no thread or handle growth |
| The xterm.js-specific scroll drain | See below |
The scroll drain specifically. useAdaptiveDrain is set from xterm.js detection, so VS Code takes d9y (a 2–3 line/frame tail) while other terminals take p9y (~75%/frame). I patched the single byte useAdaptiveDrain:i → useAdaptiveDrain:0 in the 2.1.224 binary to force the proportional drain, changing nothing else, and the bug reproduced identically. The drain is not the cause — noting it so nobody else spends time there.
Not reproducible outside the VS Code terminal
Same machine, same conversation, same settings, Windows Terminal: scrolling stays smooth indefinitely. No degradation at any point.
Control test: VS Code's terminal handles the same workload fine
To check whether this is simply a VS Code terminal limit under alt-screen scrolling, I ran less --mouse in the same VS Code terminal over two generated files, 20,000 lines each:
- plain ASCII
- dense styling: five 24-bit foreground/background spans plus box-drawing glyphs per line
Jumped to the end, then scrolled up hard with the wheel, the same motion that reproduces the bug.
Both were completely smooth, with no degradation. Same alt screen, same mouse reporting, same wheel-driven full-viewport repaints, heavier per-line styling than Claude Code emits — and VS Code's terminal handled it without trouble.
So the alt-screen scroll workload is not the problem. Something specific to Claude Code's fullscreen renderer is. (Now identified: less dirties a row or two per notch via scroll regions, fullscreen dirties the entire viewport. See the root-cause comment.)
One more observation, offered with a caveat
A Chrome DevTools performance trace of the VS Code renderer during the degraded state shows the main thread spending 17.2 s of 20.1 s of task time inside Commit, with individual commits over 1000 ms, while claude.exe is at 0% CPU and total JS across xterm.js, addon-webgl and the workbench is under 400 ms. Inside the longest commit, the GPU process is in a single 1077 ms task while using almost no CPU.
Caveat: the bug still reproduces with terminal.integrated.gpuAcceleration: "off", which should take the WebGL path out entirely, so I can't claim this is causal. Including it in case it's useful. (Resolved — forced synchronous layout bills to Commit, not to JS self-time, and is renderer-independent.)
Additional Notes
The repro is reliable and takes under a minute. Happy to run instrumentation, capture traces, or test a patched build against it.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗