zsh Zinitに変える をしたけど遅くなってきたので調査した
調査方法
〇〇envのせいでzshの起動が遅いからチューニングした - Qiita
起動速度の計測
time (zsh -i -c exit)
zprofを使ってどの処理に時間かかっているかを測定
if [ "$ZSHRC_PROFILE" != "" ]; then
zmodload zsh/zprof && zprof > /dev/null
fi
function zsh-profiler() {
ZSHRC_PROFILE=1 zsh -i -c zprof
}
コメントアウトしながらどれが遅いかを調査
やったこと
compinitを1回だけ実行するようにした
複数回実行している箇所があったので直した
brew --prefix
コマンドを1回だけ実行するようにした
brewで入れたコマンドにpathを通すために、毎回 $(brew --prefix)
でbrewのディレクトリを取得していたが、これが結構時間がかかっていた。
path=(
$(brew --prefix)/opt/coreutils/libexec/gnubin(N-/) # coreutils
$(brew --prefix)/opt/ed/libexec/gnubin(N-/) # ed
$(brew --prefix)/opt/findutils/libexec/gnubin(N-/) # findutils
$(brew --prefix)/opt/gnu-sed/libexec/gnubin(N-/) # sed
$(brew --prefix)/opt/gnu-tar/libexec/gnubin(N-/) # tar
$(brew --prefix)/opt/grep/libexec/gnubin(N-/) # grep
${path}
)
manpath=(
$(brew --prefix)/opt/coreutils/libexec/gnuman(N-/) # coreutils
$(brew --prefix)/opt/ed/libexec/gnuman(N-/) # ed
$(brew --prefix)/opt/findutils/libexec/gnuman(N-/) # findutils
$(brew --prefix)/opt/gnu-sed/libexec/gnuman(N-/) # sed
$(brew --prefix)/opt/gnu-tar/libexec/gnuman(N-/) # tar
$(brew --prefix)/opt/grep/libexec/gnuman(N-/) # grep
${manpath}
)
↓
export BREW_PREFIX=$(brew --prefix)
path=(
$BREW_PREFIX/opt/coreutils/libexec/gnubin(N-/) # coreutils
$BREW_PREFIX/opt/ed/libexec/gnubin(N-/) # ed
$BREW_PREFIX/opt/findutils/libexec/gnubin(N-/) # findutils
$BREW_PREFIX/opt/gnu-sed/libexec/gnubin(N-/) # sed
$BREW_PREFIX/opt/gnu-tar/libexec/gnubin(N-/) # tar
$BREW_PREFIX/opt/grep/libexec/gnubin(N-/) # grep
$BREW_PREFIX/opt/mysql-client/bin(N-/) # mysql
${path}
)
manpath=(
$BREW_PREFIX/opt/coreutils/libexec/gnuman(N-/) # coreutils
$BREW_PREFIX/opt/ed/libexec/gnuman(N-/) # ed
$BREW_PREFIX/opt/findutils/libexec/gnuman(N-/) # findutils
$BREW_PREFIX/opt/gnu-sed/libexec/gnuman(N-/) # sed
$BREW_PREFIX/opt/gnu-tar/libexec/gnuman(N-/) # tar
$BREW_PREFIX/opt/grep/libexec/gnuman(N-/) # grep
${manpath}
)
zinit → sheldon に移行した
パッケージマネージャはもともと zplug を使っていて、1年くらい前に zinit に移行したが、あるとき作者さんがリポジトリを削除して、現在あるのはfork版となっている。 メンテナンスに不安を感じたのと、設定が難しいなと感じていたので sheldon に移行した。
.zshrc
# zshrcにはこれだけ
eval "$(sheldon source)"
~/.config/sheldon/plugins.toml
shell = "zsh"
# zsh-deferを使って、デフォルトで遅延読み込みする
apply = ["defer"]
[plugins.zsh-defer]
github = "romkatv/zsh-defer"
apply = ["source"]
[templates]
defer = { value = 'zsh-defer source "{{ file }}"', each = true }
[plugins.compinit]
inline = 'autoload -Uz compinit && compinit'
[plugins.fast-syntax-highlighting]
github = "zdharma-continuum/fast-syntax-highlighting"
[plugins.zsh-completions]
github = "zsh-users/zsh-completions"
[plugins.zsh-autosuggestions]
github = "zsh-users/zsh-autosuggestions"
[plugins.zsh-history-substring-search]
github = "zsh-users/zsh-history-substring-search"
# remoteのshellを実行する
[plugins.aws_zsh_completer]
remote = "https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_zsh_completer.sh"
[plugins.dotfiles-defer]
local = "~/.config/zsh"
use = ["{functions}.zsh"]
# 同期的に読み込みたいものは source を指定する
[plugins.dotfiles-sync]
local = "~/.config/zsh"
use = ["{options,plugins}.zsh"]
apply = ["source"]
これにより、ほとんどの設定やプラグインを非同期で読み込むようになり起動時には時間があまりかからなくなった。
結果
- もともと1.4sかかっていたのが、
brew --prefix
の改善で500msまで早くなった - zinit → sheldon移行で200msまで早くなった