zsh の起動を500%高速化した話

  • 5
    Like
  • 0
    Comment

高速化の敵

  1. 外部スクリプトロード (最も遅い)
  2. zsh 関数定義
  3. zsh スクリプト実行

高速化の味方

  1. 分離された実行可能ファイル
  2. autoload による遅延ロード
  3. 複数 zsh ファイルの統合

実践したテクニック集

tmux の起動を高速化

tmux を起動するのに zsh プラグインは不要。

.zshrc
if [[ -z "$TMUX" ]]
then
  tmux new-session;
  exit;
fi

# プラグインのロード処理

遅延ロード

.zshrc
zplug 'zsh-users/zsh-completions', use:'src/_*', lazy:true
.zshrc
zplug 'mollifier/anyframe', \
    use:'anyframe-functions/{actions,selectors,sources,widgets}/*', lazy:true

zle -N anyframe-widget-cd-ghq-repository
# ...
bindkey '^x^g' anyframe-widget-cd-ghq-repository
# ...

実行ファイルとしてロード

特に補完定義ファイルは分離されていることが多い! ( compdef の埋め込み忘れに注意)

.zshrc
zplug 'simonwhitaker/gibo', use:'gibo', as:command
.zshrc
zplug 'motemen/ghq', dir:"${GOPATH}/src/github.com/motemen/ghq", \
    use:'zsh/_ghq', as:command

compdef _ghq ghq

コマンド実行時にロード

.zshrc
zplug 'supercrabtree/k', use:'!*'

k() {
  unfunction k
  . "${ZPLUG_REPOS}/supercrabtree/k/k.sh"

  k "$@"
}

zplug のプラグインチェックをスキップ

新規プラグインを追加した際に手動で zplug install && zplug load する必要があるので注意。

.zshrc
# if ! zplug check --verbose; then
#     printf "Install? [y/N]: "
#     if read -q; then
#         echo; zplug install
#     fi
# fi

zsh ファイルをコンパイル

上のテクニックを実践するとコンパイラが追えない処理が少なくなるはずなので相性がいいはず (?)

$ zcompile ~/.zshrc; zcompile ~/.zsh/rc/plugins.rc.zsh

こちらもおすすめです。
https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/zsh_reload

後書き

測るのを忘れてしまったのですが、体感的に 5s 以上かかっていた zsh の起動が 1s 以内で起動するようになりました。 (ほとんどのプラグインが oh-my-zsh から引っ張ってきた補完ファイル)
もっと良い方法や「それもっと簡単に書けるよ!」などがあれば教えてください。