私たちはソフトウェア開発において、頻繁にターミナルを使用します。特にZshのような強力なシェルは、その豊富な機能とカスタマイズ性により、私たちの手助けをしてくれます。しかし、その一方で、Zshの起動が遅くなる問題があります。それは一体何が原因で、どう改善できるのでしょうか。この記事では、その問題と解決策について見ていきましょう。
コマンドの補完とパフォーマンス
Zshでは、多くのコマンドに対して補完機能を提供しています。また、多くのコマンドラインツールも自身の補完機能を提供し、それを.zshrc
に追加するように指示しています。例えば、op
コマンドは以下のように補完機能を提供します。
eval "$(op completion zsh)"
しかし、こうした補完スクリプトを気軽に.zshrc
に追加していくと、Zshの起動時間がぐんと増えてしまいます。.zshrc
に書かれたものは、新しいターミナルセッションを開始するたびに読み込まれるからです。
遅延ローディング(オンデマンドローディング)を利用しよう
そこで、補完スクリプトを「遅延ローディング」または「オンデマンドローディング」させる方法を紹介します。これは補完スクリプトを必要になったときだけロードするというアイデアです。具体的には、以下のように設定します。
function _op() {
unfunction "$0"
eval "$(op completion zsh)"
$0 "$@"
}
compdef _op op
このスクリプトは次のように働きます。
-
_op
という新しい関数を定義します。 - この関数の中で、まず関数自身を削除します。
- 次に
eval
のところでop
の補完を生成します。 - 最後に生成した補完コマンドを、元の
_op
コマンドを同じ引数で実行します。 - これにより、
_op
関数は一度だけ評価され、それ以降は生成された補完コマンドが直接呼ばれます。
このようにして、補完が必要になったときだけ補完をロードします。
パフォーマンスの向上
この改善により、zshの起動時間が大幅に短縮されました。
ためしに、施策前の書き方と施策後の書き方を100回繰り返してからzshを起動するようにしてみました。
その結果、施策前の方法では起動に4.7秒かかったのに対し、遅延ローディングを利用した方法ではわずか0.3秒となりました。
つまり、起動時間が約94%短縮され、大きなパフォーマンスの改善が見られました。
まとめ
Zshの起動時間の問題は、命令を遅延ローディング(オンデマンドローディング)させることで解決することができました。このように単純な変更がパフォーマンスに大きな影響を与えることがあります。この経験が、皆さんの作業を少しでも効率化するのに役立つことを願っています。