VSCodeのターミナルが片方のPCだけ遅い → 犯人は Screen Reader: yes だった話
TL;DR
- 同じリモート環境にSSH接続しているのに、片方のPCだけClaude Code(統合ターミナル)のスクロールが重い
- GPUもCPUもメモリも余裕があり、拡張機能を切っても直らない
-
code --statusで2台を比較したら、唯一の差分がScreen Reader: yes/noだった - スクリーンリーダーを検出するとVSCodeがターミナル描画を GPUベースからDOMベースに切り替える ため重くなる
-
editor.accessibilitySupportを"off"に固定したら解決
{
"editor.accessibilitySupport": "off"
}
症状
リモートのワークステーションにSSH接続し、VSCodeの統合ターミナルでClaude Codeを動かしている。あるPCではターミナルのスクロールが明らかにカクつく。一方、同じワークステーション・同じネットワークに別のPCからSSH接続すると快適。
つまりサーバ側でもネットワークでもなく、遅い方のローカルPC(クライアント)側に原因がある、という切り分けができる。
試したが効かなかったこと
最初に疑った定番の設定はどれも空振りだった。
-
terminal.integrated.scrollbackを1000まで削減 → 変化なし -
terminal.integrated.gpuAccelerationを"auto"に → 変化なし - 拡張機能を全無効化(
--disable-extensions/Developer: Reload Window With Extensions Disabled)→ 変化なし
リソース不足でもなく拡張機能でもない。ここで code --status の出番になる。
code --status で2台を比較する
VSCodeが起動している状態でターミナルから実行すると、GPU状態やプロセス一覧などの診断情報がまとめて出力される。
code --status
2台の出力を並べて見比べたところ、GPUは両方とも正常だった。
GPU0: Intel(R) Arc(TM) Graphics ... *ACTIVE*
gpu_compositing: enabled
rasterization: enabled
webgl: enabled
CPU・メモリも全プロセスがほぼ0%で余裕。レンダリングパスもリソースも問題なし。
そして、ほぼ唯一の明確な差分がこれだった。
| 遅いPC | 快適なPC | |
|---|---|---|
| Screen Reader | yes | no |
なぜ Screen Reader: yes だと遅くなるのか
ここが今回の本質。VSCode(Electron / Chromium)はターミナルの描画方式を状況に応じて切り替えている。
- GPU描画(canvas / webgl): 文字をピクセルとしてキャンバスに直接塗る。速い。ただし出力は「絵」であって、各行・各文字の構造情報は残らない。
- DOM描画: ターミナルの各行・各文字を実際のHTML要素として組み立てる。重い。ただしアクセシビリティツリーが生成され、スクリーンリーダーが内容を読み取れる。
スクリーンリーダーは画面のピクセルではなく、アプリ内部のアクセシビリティツリー(構造化された意味情報)を読む。GPU描画の「一枚絵」では中身が空っぽに見えて読めないため、スクリーンリーダーを検出するとVSCodeは読めるDOM描画にフォールバックする。
その結果、ターミナルに数千行の要素が並ぶような状況でレンダリングが重くなり、スクロールがカクつく。
accessibilitySupport: "auto"(デフォルト)
└─ SR検出 = yes → DOM描画(読めるが重い) ← 今回ハマったルート
└─ SR検出 = no → GPU描画(軽い)
ちなみにこの「速いcanvas描画 vs 読めるDOM描画」のトレードオフは、canvasベースのWebアプリ全般(Google Docs、Figmaなど)が共通で抱えている問題で、各社はアクセシビリティ用に別途DOMレイヤーを用意するなどして対処している。
なぜ使っていないのに yes になるのか
実際にスクリーンリーダー(Windowsのナレーターなど)を使っていなくても、何らかのソフトがアクセシビリティAPIを叩いていると Screen Reader: yes と判定されることがある。accessibilitySupport のデフォルト "auto" はこの検出結果に従うため、誤検出するとそのままDOM描画ルートに入ってしまう。
解決策
検出ロジック自体をスキップして、常にGPU描画に固定する。
{
"editor.accessibilitySupport": "off"
}