Z Shell Performance
My zsh is taking so long to launch now, like up to 40 seconds, and I wanted to find out why.
So I did some Googling and found out that adding zmodload zsh/zprof to the top of my .zshrc file meant that I could run zprof (after reloading the shell). This yielded:
num | calls | time | self | name | ||||
---|---|---|---|---|---|---|---|---|
1) | 1 | 3067.88 | 3067.88 | 74.90% | 1344.09 | 1344.09 | 32.82% | nvm_auto |
2) | 2 | 909.13 | 454.57 | 22.20% | 909.13 | 454.57 | 22.20% | jenv |
3) | 2 | 1723.79 | 861.90 | 42.09% | 852.65 | 426.32 | 20.82% | nvm |
4) | 1 | 779.97 | 779.97 | 19.04% | 710.71 | 710.71 | 17.35% | nvm_ensure_version_installed |
5) | 1 | 90.30 | 90.30 | 2.20% | 72.26 | 72.26 | 1.76% | nvm_die_on_prefix |
6) | 1 | 69.26 | 69.26 | 1.69% | 69.26 | 69.26 | 1.69% | nvm_is_version_installed |
7) | 1 | 47.94 | 47.94 | 1.17% | 47.94 | 47.94 | 1.17% | handle_completion_insecurities |
8) | 1 | 18.56 | 18.56 | 0.45% | 18.56 | 18.56 | 0.45% | compinit |
9) | 2 | 17.09 | 8.54 | 0.42% | 17.09 | 8.54 | 0.42% | nvm_grep |
10) | 2 | 12.73 | 6.36 | 0.31% | 12.73 | 6.36 | 0.31% | grep-flag-available |
11) | 2 | 11.29 | 5.65 | 0.28% | 11.29 | 5.65 | 0.28% | down-line-or-beginning-search |
12) | 1 | 4.79 | 4.79 | 0.12% | 4.77 | 4.77 | 0.12% | powerlevel9k_vcs_init |
13) | 1 | 4.67 | 4.67 | 0.11% | 4.67 | 4.67 | 0.11% | termColors |
14) | 2 | 2.91 | 1.45 | 0.07% | 2.91 | 1.45 | 0.07% | env_default |
15) | 15 | 2.05 | 0.14 | 0.05% | 2.05 | 0.14 | 0.05% | up-line-or-beginning-search |
…which showed that nvm is taking a long time to load. I don’t use it a lot but I do want it sometimes so instead I’m using https://github.com/lukechilds/zsh-nvm#lazy-loading which lazy-loads nvm with some additions in the .zshrc file:
export NVM_LAZY_LOAD=true
export NVM_COMPLETION=true
plugins=(zsh-nvm [plus your others])
It’s gone from around 40 seconds to around 4 seconds!
However rbenv
and jenv
are also slow! I couldn’t find a reasonably easy way to improve that but I am using evalcache which will cache the init commands, saving some time.
Installed with:
git clone https://github.com/mroth/evalcache ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/evalcache
…and in .zshrc:
plugins=(evalcache [plus your others])
Then instead of eval "$(jenv init -)"
in your .zshrc
use _evalcache jenv init -
Sadly that’s one less excuse though…