zsh の起動が遅い理由(とその修正方法)
新しいターミナルタブを開く。待つ。1秒が過ぎ、2秒、そして3秒。ようやく zsh のプロンプトが表示される。このイライラする遅延はシェル自体の問題ではなく、ほぼ常にあなたの設定に原因があります。
バニラの zsh インストールは約50〜100ミリ秒で起動します。起動時間が数秒に膨れ上がる場合、原因は予測可能です:補完システムのオーバーヘッド、同期的なプラグイン読み込み、重いテーマ、そして nvm や pyenv のような言語バージョンマネージャーです。このガイドでは、実際に何が遅いのかを特定し、設定全体を書き直すことなく修正する方法を示します。
重要なポイント
- 標準の zsh は50〜100msで起動します。数秒の遅延は、シェル自体ではなく
.zshrcに起因します。 - 何かを変更する前に、
zsh/zprofと/usr/bin/time zsh -i -c exitを使用して実際のボトルネックを特定してください。 - 言語バージョンマネージャー(nvm、pyenv、conda)が最も一般的な原因です—遅延読み込みで即座に改善できます。
compinitを正確に1回だけ呼び出し、未使用のプラグインを削減し、軽量なテーマを使用することで、さらに起動時間を短縮できます。
最適化の前にプロファイリングを
推測は時間の無駄です。Zsh には、起動時間がどこに費やされているかを正確に明らかにする組み込みのプロファイラーが含まれています。
~/.zshrc の最初の行に以下を追加してください:
zmodload zsh/zprof
最後の行に以下を追加してください:
zprof
新しいターミナルを開くと、次のような出力が表示されます:
num calls time self name
1) 1 442.05 84.53% 254.54 48.68% nvm_auto
2) 2 187.51 35.86% 91.66 17.53% nvm
3) 1 75.70 14.48% 64.37 12.31% nvm_ensure_version_installed
self 列は、他のプロファイルされた関数への呼び出しを除いた、各関数で費やされた時間を示します。最も大きい数値から対処してください。
実時間測定には、以下を使用します:
/usr/bin/time zsh -i -c exit
これを複数回実行してください—最初の実行にはコールドキャッシュの影響が含まれる可能性があります。
最も一般的なボトルネック
言語バージョンマネージャー(nvm、pyenv、conda)
これらは zsh 起動が遅くなる最大の原因です。デフォルトの nvm 初期化だけで300〜500msを追加する可能性があります。
修正方法:遅延読み込み。 これらのツールを実際に呼び出すまで初期化しないでください。
nvm の場合、標準の初期化ブロックを以下に置き換えます:
export NVM_DIR="$HOME/.nvm"
nvm() {
unfunction nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm "$@"
}
エイリアスではなくラッパー関数を使用する方がここではより堅牢です。エイリアスベースのアプローチは、nvm が間接的に(例えば、スクリプトや別の関数によって)呼び出された場合に壊れる可能性があります。これは、エイリアスがインタラクティブなトップレベルのコマンド位置でのみ展開されるためです。一方、関数はすべてのコンテキストで実際のコマンドのように動作します。
Oh-My-Zsh を使用している場合は、遅延読み込みで nvm プラグインを有効にします:
zstyle ':omz:plugins:nvm' lazy yes
plugins=(git nvm)
このアプローチにより、あるユーザーの起動時間が430msから140msに短縮され、70%の改善が見られました。
compinit が複数回呼び出される
compinit 関数は zsh の補完システムを初期化します。これは負荷が高く、フレームワークが誤って複数回呼び出すことがよくあります。
ベストプラクティス: すべての $fpath の変更が完了した後、compinit を正確に1回だけ呼び出します。
# 最初に fpath に追加
fpath=($ZSH_CUSTOM/plugins/zsh-completions/src $fpath)
# その後、補完を初期化
autoload -Uz compinit && compinit
.zcompdump ファイルが古いか破損している場合は、再生成してください:
rm -f ~/.zcompdump
compinit
compinit -C を使用するとセキュリティチェックをスキップしてより高速になりますが、有効にする前にトレードオフを理解してください:補完ファイルが改ざんされているか、別のユーザーが所有している場合に警告されません。
Discover how at OpenReplay.com.
プラグインが多すぎる
各プラグインは起動時に同期的にファイルを読み込みます。プラグインリストを厳しく監査してください。
実際に使用しているプラグインを確認してください。github と brew プラグインは特に遅いことで知られています。週に一度も使用しないものは削除してください。
重いテーマ
git ステータスを照会したり、ネットワークリソースをチェックしたり、サブプロセスを実行する複雑なテーマは、顕著な遅延を追加します。
Powerlevel9k を使用している場合は、Powerlevel10k に切り替えてください。これはドロップイン置換で、プロンプトを10〜100倍高速にレンダリングします。Instant Prompt 機能を有効にすると、瞬時に起動したかのように感じられます。
Oh-My-Zsh の自動更新チェック
Oh-My-Zsh の更新チェックはシェル起動のたびに実行され、起動時間を支配する可能性があります。無効にしてください:
DISABLE_AUTO_UPDATE="true"
必要なときに手動で omz update を実行できます。
高速起動のためのクイックウィン
- プラグイン数を減らす – 設定から未使用のプラグインを削除します。
- バージョンマネージャーを遅延読み込み – nvm、pyenv、conda はオンデマンドで読み込むべきです。
- compinit を1回だけ呼び出す – すべての fpath 変更が完了した後に。
- 軽量なテーマを使用 – または Powerlevel10k の Instant Prompt を有効にします。
- 自動更新を無効化 – 代わりに手動で更新を確認します。
「高速」が実際にどのようなものか
適切に最適化された Oh-My-Zsh を使用した zsh 設定は、150〜300msで起動するはずです。フレームワークなしでは、50〜100msが達成可能です。500msを超えている場合、何か具体的な問題があります—そして zprof がそれを示してくれます。
結論
盲目的に最適化しないでください。起動をプロファイリングし、実際のボトルネックを特定し、的を絞った修正を適用してください。ほとんどの開発者は、1つのバージョンマネージャーを遅延読み込みし、いくつかの未使用プラグインを削除することで、10分以内に zsh の起動時間を50〜80%削減できます。
測定が終わったら、.zshrc から zprof の行を削除することを忘れないでください。
よくある質問
いいえ。素の zsh インストールは bash と同じくらい速く起動し、通常100ミリ秒未満です。認識される遅さは、ほぼ常に .zshrc が起動時に読み込むもの(プラグイン、テーマ、バージョンマネージャーなど)に起因し、シェル自体からではありません。
実際には壊れません。遅延読み込みは、セッションで nvm、node、npm、または npx を初めて実行したときに、nvm とその管理する Node バージョンが読み込まれることを意味します。その最初の呼び出しの後は、すべてが以前と全く同じように動作します。唯一の違いは、シェルがより速く起動することです。
.zshrc の先頭に zmodload zsh/zprof を、末尾に zprof を追加してプロファイリングを有効にした zsh を実行してください。出力で、compinit または compdump の横にある複数の呼び出しを探してください。calls 列に1より大きい数値が表示されている場合、設定が補完を冗長に初期化しています。
必ずしもそうではありません。Oh-My-Zsh 自体が追加するオーバーヘッドは控えめです。遅延は、それを通じて読み込まれる特定のプラグインとテーマから来ています。プラグインリストを削減し、バージョンマネージャーを遅延読み込みし、Powerlevel10k のような高速なテーマに切り替えることで、通常、フレームワークを放棄することなく起動時間を300ミリ秒未満にできます。
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.