📑
nvmを遅延ロードしてzsh起動を高速化する方法
Node.jsの公式ドキュメントではnvmを使ったインストールが推奨されていますが、nvmを有効にするとシェル起動が遅くなります。
本記事では、nvmを遅延ロードすることでzshの起動を快適にする方法をご紹介します。
課題:nvmの自動読み込みがシェル起動を遅くする
公式インストーラーは.zshrc
に以下の設定を追記します:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
この設定により、zsh起動時に毎回nvm.shが読み込まれるため、プロンプトが表示されるまでにかなりの遅延が発生します。
解決策:nvmを遅延ロードする
以下の設定に置き換えることで、初回にnvmコマンドを実行したタイミングでのみnvm.shを読み込むようにします。これにより、シェル起動は高速のまま、nvmも通常どおり使えます。
if [ -d ${HOME}/.nvm ]; then
# Set NVM_DIR if not already set
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
# Lazy load NVM
nvm() {
unset -f nvm
source "${NVM_DIR}/nvm.sh"
nvm "$@"
}
# Add default Node version to PATH if it exists
if [ -f "${NVM_DIR}/alias/default" ]; then
DEFAULT_NODE_VERSION=$(cat "${NVM_DIR}/alias/default")
NODE_BIN_PATH="${NVM_DIR}/versions/node/v${DEFAULT_NODE_VERSION}/bin"
if [ -d "${NODE_BIN_PATH}" ]; then
export PATH="${NODE_BIN_PATH}:$PATH"
export NODE_PATH="${NVM_DIR}/versions/node/v${DEFAULT_NODE_VERSION}/lib/node_modules"
fi
fi
fi
注意点:上記コードではbash補完(bash_completion
)を削除していますが、必要であれば同様に遅延ロードしてください。
遅延ロードの仕組み
- シェル起動時はnvm.shを読み込まないため、高速に起動
-
nvm
コマンドを呼ぶと関数nvm()が動作 - 関数内で実際のnvm.shを読み込み
-
unset -f nvm
で自身の関数定義を削除 -
nvm "$@"
で本来のnvmコマンドを再実行
必要な準備:デフォルトバージョンの設定
初回のシェル起動後に以下を実行して、デフォルトNodeバージョンを設定しておきます:
# installしたバージョンをdefaultに指定する
$ nvm alias default 22.17.0
この操作により、${HOME}/.nvm/alias/default
にバージョン番号が書き込まれ、次回以降のシェル起動時に自動でそのバージョンのPATHが追加されます。
おまけ:.zshrcの上書きを防止する
bunもそうですが、フロントエンド界隈は.zshrc
をインストール時に勝手に書き換えるソフトウェアが多い印象です。なぜこんなことをするのか理解できませんが、コミュニティとしてPATH周りのトラブル回避を優先しているためと推測します。
bunには.zshrc
に# bun completions
というコメントを追加しておくと追記をスキップする仕組みがあります。
残念ながらnvmには同様の仕様がありません。そこでPRを出しました。
マージされるかは不透明ですが、動向をチェックしてみてください。
Discussion
zshの起動が遅くてまさに困ってました。
この記事を参考に解決できました。
ありがとうございます!