WezTermでWSL2のEnterがもっさりした。描画方式を試し、プロンプトと起動経路を見直した

WezTerm上のWSL2でEnterを押すと、わずかに引っかかる。操作できないほど遅いわけではありません。ただ、何度も繰り返す動作なので気になりました。

最初はNeovimの設定か、WezTermの描画が原因だと思っていました。しかし、同じWSL2をWindows Terminalから使うと軽い。今回の環境では、Starshipがプロンプトを作る時の処理を減らし、PowerShellを経由せずWSL2を直接起動すると、引っかかりが小さく感じられました。

OpenGLからWebGpuへ描画方式を変えても、私の体感は変わりませんでした。描画方式だけでは今回の引っかかりを説明できなかったため、元へ戻しています。

Neovimを測っても、引っかかりの説明がつかなかった

もともとは、Neovimの文字入力やカーソル移動が遅いのではないかと疑っていました。Headless環境でキー処理を2,000回ずつ測ると、文字入力やjwnの中央値はいずれも1ms未満でした。

この測定にWezTermの画面描画や物理キーボードは含まれません。それでも、Neovim内部のキー処理だけを削っても、Enter後の体感は変わりそうにない。ここで端末とシェルを分けて見ることにしました。

普段の環境構成は、AIにコードを書かせる時代に、WezTerm・WSL2・Neovimを整えた理由に書いています。今回はNeovimではなく、その手前にあるWezTermとZshの話です。

描画方式を変えても、変わらんね

WezTermの標準キーバインドを無効にしていたため、診断画面を開くCtrl+Shift+Lも使えない状態でした。keybinds.luaへ診断用のキーを追加し、Debug Overlayを開きました。

{
  key = "L",
  mods = "CTRL|SHIFT",
  action = wezterm.action.ShowDebugOverlay,
}

Lua REPLでGPUを列挙すると、Intel UHD GraphicsがVulkan、DirectX 12、OpenGLの候補として表示されました。この表示だけで実際の描画経路までは確定しませんが、GPUがまったく候補に出ない状態ではありませんでした。

wezterm.gui.enumerate_gpus()

設定はもともとOpenGLでした。WindowsではWebGpuからDirectX 12を利用できるため、WebGpuへ変えて比較しました。

config.front_end = "WebGpu"

WezTermを終了して起動し直し、同じWSL2でEnterを押しました。変わらんね。OpenGLへ戻して、次はプロンプトを調べました。

StarshipがEnterのたびに言語環境を調べていた

次にZshのプロンプトを調べました。私のStarship設定には、ディレクトリとGitだけでなく、Python、Node.js、C、C++、Rust、Go、Java、Docker、Conda、Pixiなどを並べていました。

見た目は楽しい。ただ、Enter後に新しいプロンプトを表示するたび、必要なモジュールの判定が動きます。

同じディレクトリでstarship promptを複数回実行し、変更前と軽量な仮設定を見比べました。これはStarship単体の切り分けで、WezTermの描画時間は入っていません。

当時は計時コマンド、試行回数、各回の原出力を保存していませんでした。数値を使った前後比較としては再現できないため、以前の秒数表は本文から外します。次に比べる時は、同じディレクトリ、設定ファイル、試行回数を固定し、starship timingsまたはシェルの計時結果をそのまま残します。

最終的に残したのは、ユーザー名、ディレクトリ、Gitブランチ、時刻です。Git変更状態と言語環境の判定は外しました。

format = """
[](color_orange)\
[󰕈](bg:color_orange fg:color_fg0)\
$username\
[](bg:color_yellow fg:color_orange)\
$directory\
[](fg:color_yellow bg:color_aqua)\
$git_branch\
[](fg:color_aqua bg:color_bg1)\
$time\
[ ](fg:color_bg1)\
$line_break$character"""

Ubuntuのアイコンは残したかったので、$osによる毎回のOS判定ではなく固定文字にしました。Windows側のStarshipにはWindowsアイコンを固定しています。見た目を全部捨てる必要はありませんでした。

zsh-autosuggestionsの再登録も毎回は要らなかった

Starshipを軽くしても、まだ少し引っかかりました。Zshのプロンプト前処理を追うと、zsh-autosuggestionsが入力ウィジェットを毎回登録し直していました。

公式リポジトリにも、ZSH_AUTOSUGGEST_MANUAL_REBINDを設定すると、プロンプト表示前の自動再登録を止められると書かれています。Oh My Zshがプラグインを読み込む前に設定しました。

plugins=(
  git
  zsh-autosuggestions
  zsh-syntax-highlighting
)

typeset -g ZSH_AUTOSUGGEST_MANUAL_REBIND=1
source $ZSH/oh-my-zsh.sh

候補表示そのものは残っています。一方で、後からZshのウィジェット構成を変えた場合は、自分で再登録が必要になる点は残ります。機能を削除したのではなく、今の固定した構成に合わせた変更です。

miseはディレクトリ移動時だけ更新することにした

miseのZsh連携も、プロンプト表示前に環境を確認していました。私の使い方では、プロジェクトを移動した時にNode.jsや.NETなどが切り替われば足ります。

そこで、起動時にmise activate zshを実行した後、precmdだけを外しました。Zshのchpwdは残るので、ディレクトリを移動した時の更新は続きます。

eval "$(mise activate zsh)"

autoload -Uz add-zsh-hook
add-zsh-hook -d precmd _mise_hook_precmd

これは私の運用に合わせた設定です。同じディレクトリに居続けたままmiseの設定ファイルを編集した時は、自動で反映されない可能性があります。その場合はシェルを開き直すか、ディレクトリを移動して読み直します。_mise_hook_precmdはmiseが提供する内部フック名なので、miseを更新した時は同じ方法で外せるか確認します。

設定後は、同じWSL2をWindows Terminalで開いた時の方がなお軽く感じました。Starship単体の値とZsh全体の処理は測定範囲が違うため、これらを単純な前後差としては扱っていません。

WSL2を直接開くと、さらに軽く感じた

Windows TerminalではUbuntuプロファイルを選び、WSL2を直接起動していました。一方、私のWezTermは次の起動設定でした。

config.default_prog = { "pwsh.exe", "-NoLogo" }

つまり、WezTermではPowerShellを起動し、そこからwslを実行していました。そこで、PowerShellを経由せずUbuntu 24.04を直接開くショートカットを追加しました。

{
  key = "U",
  mods = "SHIFT|CTRL",
  action = wezterm.action.SpawnCommandInNewTab({
    args = { "wsl.exe", "-d", "Ubuntu-24.04" },
  }),
}

Ctrl+Shift+Uで開いたWSL2は、明らかに軽く感じました。これはフレーム時間を取った結果ではなく、同じPCでWindows Terminal、PowerShell経由のWezTerm、WSL直接起動のWezTermを触り比べた体感です。

直接起動で軽く感じたため、私の環境ではPowerShellを挟む起動経路も候補でした。ただし、プロンプト軽量化もすでに反映した後の比較です。起動経路だけでどれだけ変わったかは測れていません。

Win11側にも同じ重いStarship設定が残っていた

WSL2とWindowsは別環境です。WSL2側の~/.config/starship.tomlを直しても、Win11側のC:\Users\ユーザー名\.config\starship.tomlは変わりません。

確認すると、Win11側にも言語環境やGit変更状態を並べた設定が残っていました。こちらもディレクトリ、Gitブランチ、時刻へ絞り、Windowsアイコンだけを固定しました。PowerShellのPSReadLine、zoxide、Carapaceは変更していません。

WSL2とWin11で見た目をそろえても、設定ファイルと実行環境は別です。この点は、以前のWin11でWezTermの設定をした話へ追記したい部分でもあります。

WSL2とWin11の設定例

実設定のformatから、改善に関係する表示項目を取り出しました。以下のStarship例は読みやすくするために未使用のモジュール定義や細かな装飾を省いた説明用の簡略版で、実設定ファイルの丸写しではありません。配色は現在のWSL2・Win11側に合わせてGruvboxにしています。必要な時だけ開ける形で残します。

私は設定ファイルを丸ごと上書きせず、既存設定へ必要な部分だけ取り込みました。WSL2のディストリビューション名とフォント名は、環境に合わせて変える部分です。

WSL2:Starship設定を表示する

配置先は~/.config/starship.tomlです。

"$schema" = "https://starship.rs/config-schema.json"

format = """
[](color_orange)\
[󰕈](bg:color_orange fg:color_fg0)\
$username\
[](bg:color_yellow fg:color_orange)\
$directory\
[](fg:color_yellow bg:color_aqua)\
$git_branch\
[](fg:color_aqua bg:color_bg1)\
$time\
[ ](fg:color_bg1)\
$line_break$character"""

palette = "gruvbox_dark"

[palettes.gruvbox_dark]
color_fg0 = "#fbf1c7"
color_bg1 = "#3c3836"
color_orange = "#d65d0e"
color_yellow = "#d79921"
color_aqua = "#689d6a"
color_green = "#98971a"
color_red = "#cc241d"

[username]
show_always = true
style_user = "bg:color_orange fg:color_fg0"
style_root = "bg:color_orange fg:color_fg0"
format = "[ $user ]($style)"

[directory]
style = "bg:color_yellow fg:#1f2329"
format = "[ $path ]($style)"
truncation_length = 4
truncate_to_repo = false

[git_branch]
symbol = ""
style = "bg:color_aqua fg:#1f2329"
format = "[ $symbol $branch ]($style)"

[time]
disabled = false
time_format = "%R"
style = "bg:color_bg1 fg:color_fg0"
format = "[  $time ]($style)"

[character]
success_symbol = "[❯](bold color_green)"
error_symbol = "[❯](bold color_red)"
WSL2:zsh設定を表示する

次の内容は.zshrc全体ではなく、既存の~/.zshrcへ取り込む部分です。ZSH_AUTOSUGGEST_MANUAL_REBINDは、oh-my-zshを読み込む前に定義します。

typeset -g ZSH_AUTOSUGGEST_MANUAL_REBIND=1

# source "$ZSH/oh-my-zsh.sh"

if command -v mise >/dev/null 2>&1; then
  eval "$(mise activate zsh)"
  autoload -Uz add-zsh-hook
  add-zsh-hook -d precmd _mise_hook_precmd
fi

if command -v starship >/dev/null 2>&1; then
  eval "$(starship init zsh)"
fi

miseprecmdフックを外すと、設定更新はシェル起動時とディレクトリ移動時になります。同じディレクトリに居続けたまま設定を変更した場合は、ディレクトリを移動するかシェルを起動し直します。

Windows 11:Starship設定を表示する

配置先は%USERPROFILE%\.config\starship.tomlです。WSL2版との主な違いは、先頭のWindowsアイコンです。

"$schema" = "https://starship.rs/config-schema.json"

format = """
[](color_orange)\
[󰍲](bg:color_orange fg:color_fg0)\
[](bg:color_yellow fg:color_orange)\
$directory\
[](fg:color_yellow bg:color_aqua)\
$git_branch\
[](fg:color_aqua bg:color_bg1)\
$time\
[ ](fg:color_bg1)\
$line_break$character"""

palette = "gruvbox_dark"

[palettes.gruvbox_dark]
color_fg0 = "#fbf1c7"
color_bg1 = "#3c3836"
color_orange = "#d65d0e"
color_yellow = "#d79921"
color_aqua = "#689d6a"
color_green = "#98971a"
color_red = "#cc241d"

[directory]
style = "bg:color_yellow fg:#1f2329"
format = "[ $path ]($style)"
truncation_length = 4
truncate_to_repo = false

[git_branch]
symbol = ""
style = "bg:color_aqua fg:#1f2329"
format = "[ $symbol $branch ]($style)"

[time]
disabled = false
time_format = "%R"
style = "bg:color_bg1 fg:color_fg0"
format = "[  $time ]($style)"

[character]
success_symbol = "[❯](bold color_green)"
error_symbol = "[❯](bold color_red)"
Windows 11:WezTerm設定を表示する

wezterm.luakeybinds.luaを、どちらも%USERPROFILE%\.config\wezterm\へ置きます。PlemolJP Console NFはインストール済みの等幅フォントへ、Ubuntu-24.04wsl.exe --list --quietで表示されるディストリビューション名へ変えます。pwsh.exeを使う設定なので、PowerShell 7を入れていない場合はpowershell.exeなど、使っているシェルへ置き換えます。

wezterm.lua

local wezterm = require("wezterm")
local config = wezterm.config_builder()

config.front_end = "OpenGL"
config.ime_preedit_rendering = "Builtin"
config.font_shaper = "Harfbuzz"
config.font = wezterm.font("PlemolJP Console NF", { weight = "DemiBold" })
config.font_size = 11.0
config.line_height = 1.0
config.cursor_blink_rate = 0
config.scrollback_lines = 10000
config.window_background_opacity = 1.0
config.default_prog = { "pwsh.exe", "-NoLogo" }
config.keys = require("keybinds").keys

return config

keybinds.lua

local wezterm = require("wezterm")
local act = wezterm.action

return {
  keys = {
    { key = "L", mods = "CTRL|SHIFT", action = act.ShowDebugOverlay },
    { key = "R", mods = "CTRL|SHIFT", action = act.ReloadConfiguration },
    {
      key = "U",
      mods = "CTRL|SHIFT",
      action = act.SpawnCommandInNewTab({
        args = { "wsl.exe", "-d", "Ubuntu-24.04" },
      }),
    },
  },
}
Windows 11:PowerShellプロファイルを表示する

次の内容を、既存の$PROFILEへ必要に応じて取り込みます。未導入のコマンドやモジュールがあってもPowerShellを起動できるよう、存在を確認してから読み込みます。

if (Get-Module -ListAvailable -Name PSReadLine) {
    Import-Module PSReadLine
    Set-PSReadLineOption -PredictionSource History
}

if (Get-Module -ListAvailable -Name Terminal-Icons) {
    Import-Module Terminal-Icons
}

if (Get-Command starship -ErrorAction SilentlyContinue) {
    Invoke-Expression (&starship init powershell | Out-String)
}

if (Get-Command zoxide -ErrorAction SilentlyContinue) {
    Invoke-Expression (&zoxide init powershell | Out-String)
}

Enterのたびに、プロンプトで待っていた

今回は、Neovim、WezTermの描画方式、WSL2の順に疑いました。プロンプトを作る時の処理を減らすと引っかかりが小さく感じられました。WSL2を直接開いても軽く感じましたが、それぞれ単独でどれだけ効いたかは測れていません。

今はWezTermのOpenGL設定を維持し、Starshipの表示項目を減らし、Ubuntuアイコンは固定表示にしています。WSL2はCtrl+Shift+Uから直接開くようにしました。私の環境では、この形がいちばん引っかかりが少なく感じます。

画面のFPSや入力から描画までの時間は、まだ測れていません。だから「WezTermはWindows Terminalより遅い」と一般化するつもりもありません。私の設定では、描画方式を変えても体感は変わらず、プロンプトを軽くしてWSL2を直接開くと、引っかかりが減ったように感じました。

確認した公式情報

確認日: 2026年9月14日

コメント

タイトルとURLをコピーしました