zsh の起動が遅かったので調べたら zplug のロードに時間がかかっていると分かった。
色々調べた結果 sheldon に乗り換えて、なかなか良い感じ。
sheldon の特徴と感想
ロードは結構速いと思う。参考にしたこの記事では zinit より少しだけ速度が改善したらしい。
僕は zinit を使ったことがないので分からないが、ひとまず zplug よりは圧倒的に速い。
sheldon の特徴として、toml ファイルでのプラグイン管理がある。
これがなかなか良い。プラグインの遅延ロード設定も簡単にできるし、ローカルの設定ファイルもプラグインと同じ感覚でロードの設定ができる。
もちろん、toml だから人間にも読みやすい。
導入手順と基本的な使い方
基本的には公式 README読めば ok。
Homebrew とかで sheldon 入れて、sheldon init を実行、eval "$(sheldon source)" を ~/.zshrc とかに書けば終了。
とても簡単。
設定は ~/.sheldon/plugins.toml に記述する。sheldon init を実行すると勝手に作られる。
アップデートは次のコマンドで実行する。
$ sheldon lock --update
plugin.toml の書き方はREADME のここを読めば、だいたい分かる。
dotfiles で管理する
僕は zshrc とかの管理は dotfiles で行っていて、ファイル構成は次のようになっている。
dotfiles/zsh/
├ zshrc.zsh
├ zprofile.zsh
├ plugin.toml
├ defe/
│ ├ alias.zsh
│ ├ completion.zsh
│ └ env-init.zsh
└ sync/
├ alias.zsh
├ option.zsh
└ prompt.zsh
zshrc.zsh には eval "$(sheldon source)" の 1 行しか書いていない。
plugins.toml は次のようになっている。
shell = 'zsh'
[plugins.zsh-defer]
github = 'romkatv/zsh-defer'
apply = ['source']
[templates]
defer = { value = 'zsh-defer source "{{ file }}"', each = true }
[plugins.compinit]
inline = 'autoload -Uz compinit && zsh-defer compinit'
[plugins.colors]
inline = 'autoload -Uz colors && zsh-defer colors'
[plugins.zsh-autosuggestions]
github = 'zsh-users/zsh-autosuggestions'
apply = ['defer']
[plugins.zsh-syntax-highlighting]
github = 'zsh-users/zsh-syntax-highlighting'
apply = ['defer']
[plugins.dotfiles-sync]
local = '~/dotfiles/zsh/sync'
use = ['*.zsh']
apply = ['source']
[plugins.dotfiles-defer]
local = '~/dotfiles/zsh/defer'
use = ['*.zsh']
apply = ['defer']
少し説明すると、
apply = ['defer'] を指定したのは遅延読み込み、apply = ['source'] を指定したものは zsh 起動時に読み込まれる。
defer は [template] によって定義されているもので、プラグイン zsh-defer を利用していることがわかる。
[templates]
defer = { value = 'zsh-defer source "{{ file }}"', each = true }
自分が書いている設定ファイルは [plugin-dotfiles-sync] と [plugin-dotfiles-defer] で読み込んでいる。
sync の方には起動時に読み込んでおく必要があるものをおいて、それ以外は defer って感じにしている。option.zsh は defer にしたかったのだけど、一部オプションは遅延読み込みが上手くいかないっぽい。だからと言って alias.zsh みたいに分離するのも面倒だったので全部 sync にしている。
あと、env-init.zsh には pyenv と rbenv の init を行っている。最適化をしていない場合、zsh 起動時間で ○○env の init は大きな時間を占めていると思う(もちろん僕もその 1 人であった)。
defer を指定するだけでこれが解消されるのは非常に手軽で嬉しい。
速度
手軽に次のコマンドで測定してみた。
$ time ( zsh -i -c exit )
zplug の時の速度を測りたかったのだけど「zplug コマンドが見つからない」エラーが出て、ちゃんと計測できなかったので、ここの方法を参考にプロファイルをとってみた。その結果、zplug と名前のついた処理についてだけで 800ms を超える時間がかかっていた(2018 年 MacBook Pro)。
sheldon に乗り換えて、十数回ほど計測した結果、2018 年 MacBook Pro では 50ms ほど、2021 年 MacBook Pro では 40ms ほどであった。
素晴らしい。