Seit einiger Zeit nervt es mich, dass mein ZSH Shell sich gefühlt sehr träge öffnet. Heute habe ich mich endlich an den Rechner gesetzt und versucht das ganze etwaszu beschleunigen. Aber was soll ich denn beschleunigen?
Nach kurzer Recherche habe ich herausgefunden, dass es einen eingebauten Profiler in der ZSH gibt. Diesen kann am aktivieren indem man in der ersten Zeile der ~/.zshrc folgendes einträgt:
zmodload zsh/zprof
Danach wird beim Starten einer neuen Shell alle Befehle und der deren Laufzeit im Hintergrund aufgezeichnet. Ein Protokoll kann man erhalten indem man den Befehl zprof
aufruft. Am besten startet man eine neuen Shell und beendet diese direkt wieder. Die Gesamtlaufzeit lässt sich zusätzlich mit dem netten time
Befehl ermitteln.
time zsh -i -c "zprof && exit"
Die Ausgabe meiner Shell sah nun wie folgt aus.
num calls time self name
-----------------------------------------------------------------------------------
1) 1 120,03 120,03 97,98% 52,17 52,17 42,59% zgen-init
2) 2 27,64 13,82 22,56% 27,64 13,82 22,56% compinit
3) 1 14,58 14,58 11,90% 14,58 14,58 11,90% handle_completion_insecurities
4) 1 7,56 7,56 6,17% 7,56 7,56 6,17% _zsh_highlight_bind_widgets
5) 1 6,58 6,58 5,37% 6,45 6,45 5,26% _zsh_highlight_load_highlighters
6) 3 2,97 0,99 2,43% 2,97 0,99 2,43% colors
7) 4 1,75 0,44 1,43% 1,75 0,44 1,43% _update_prompt
8) 1 1,77 1,77 1,44% 1,74 1,74 1,42% powerlevel9k_vcs_init
9) 1 1,25 1,25 1,02% 1,25 1,25 1,02% detect-clipboard
10) 36 1,44 0,04 1,18% 1,19 0,03 0,97% set_default
11) 1 1,10 1,10 0,89% 1,10 1,10 0,89% termColors
12) 10 1,02 0,10 0,83% 1,02 0,10 0,83% compdef
13) 7 1,00 0,14 0,82% 1,00 0,14 0,82% add-zsh-hook
14) 1 5,10 5,10 4,16% 0,77 0,77 0,63% prompt_powerlevel9k_setup
15) 3 0,62 0,21 0,51% 0,62 0,21 0,51% is-at-least
16) 41 0,31 0,01 0,25% 0,31 0,01 0,25% defined
17) 1 0,18 0,18 0,15% 0,18 0,18 0,15% (anon)
18) 2 0,06 0,03 0,05% 0,06 0,03 0,05% segment_in_use
19) 1 0,08 0,08 0,07% 0,04 0,04 0,04% print_deprecation_warning
20) 2 0,04 0,02 0,03% 0,04 0,02 0,03% env_default
21) 1 0,04 0,04 0,04% 0,03 0,03 0,03% zgen
22) 1 0,02 0,02 0,02% 0,02 0,02 0,02% bashcompinit
23) 1 0,01 0,01 0,01% 0,01 0,01 0,01% zgen-saved
Wie man sieht geht ein großer Teil der Zeit auf zgen init drauf.
Nicht vergessen sollte man, den Profiler in der .zshrc Datei nach dem Benchmark wieder zu deaktivieren!
Umstellung von zgen auf zplug
Im Zuge der Performance-Analyse habe ich meine ZSH Plugin von zgen auf zplug umgestellt was einiges schneller sein soll. Das scheint bei mir auch einiges gebracht zu haben. Die Startgeschwindigkeit hat sich um ca. 20% verbessert. Eine kleine Anleitung zur Migration gibt es hier: https://github.com/zplug/zplug/wiki/Migration
Meine Logik zum Laden von zplug Plugin sieht nun so aus:
# Check if zplug is installed
if [[ ! -d ~/.zplug ]]; then
git clone https://github.com/zplug/zplug ~/.zplug
source ~/.zplug/init.zsh && zplug update --self
fi
source "${HOME}/.zplug/init.zsh"
# Make sure to use double quotes to prevent shell expansion
zplug "plugins/command-not-found", from:oh-my-zsh
zplug "plugins/git", from:oh-my-zsh
zplug "plugins/sudo", from:oh-my-zsh
zplug "plugins/ssh", from:oh-my-zsh
zplug "plugins/z", from:oh-my-zsh
zplug "plugins/shrink-path", from:oh-my-zsh
zplug "bhilburn/powerlevel9k", use:powerlevel9k.zsh-theme
zplug "zsh-users/zsh-completions"
zplug "zsh-users/zsh-autosuggestions"
zplug "zsh-users/zsh-syntax-highlighting", defer:2
zplug "zsh-users/zsh-history-substring-search", defer:3
zplug "junegunn/fzf", use:"shell *.zsh"
zplug "junegunn/fzf", as:command, hook-build:"./install --bin", use:"bin/{fzf-tmux,fzf}"
# Install packages that have not been installed yet
if ! zplug check; then
printf "Install? \[y/N\]: "
if read -q; then
echo; zplug install
else
echo
fi
fi
zplug load
Bei der Analyse habe ich gleich noch ein paar Dinge entfernt die ich nicht wirklich benötigt habe. Jetzt startet bei mir eine Shell wieder blitzschnell.
time zsh -i -c "exit"
zsh -i -c "exit" 0,19s user 0,09s system 113% cpu 0,244 total