Make your shell 370.52% faster with this easy trick (fix nvm startup times)

zsh was slow. A shell should not take nearly a full second to start. 814 milliseconds may not sound like a lot, but it’s extremely noticeable, especially when creating new terminal tabs or sshing into a server.

Time how long it takes for zsh to start:

time zsh -i -c echo

I was seeing upwards of 0.81 to 0.90 seconds on my MacBook (and worse on my spinning rust servers) for zsh.

Blanking out my .zshrc, my shell startup time dropped to below 0.03 seconds. Therefore I figured I was misconfiguring zsh. Commenting out lines one by one, the culprit was clear: nvm.

This is because I was using nvm installed using the recommended install.sh script. From my testing, this is fine in bash, but destroys zsh startup times.

Fix it #

To fix this, I used zsh-nvm, which has the ability to enable Lazy Loading - aka, only initializing nvm when I call any node-y programs for the first time. I know that zsh plugin managers exist, but they seem excessive to me, so I just copied the zsh-nvm.plugin.zsh script into a file at ~/.zsh-nvm.zsh

Then, simply comment out the auto-generated nvm lines from your .zshrc:

# export NVM_DIR="$HOME/.nvm"
# [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
# [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

And add these lines (with the correct path for where you saved the zsh-nvm file):

export NVM_LAZY_LOAD=true
source "/Users/varun/.zsh-nvm.zsh"

Before:

time zsh -i -c echo
# --> zsh -i -c echo  0.38s user 0.40s system 94% cpu 0.814 total

After:

time zsh -i -c echo
# --> zsh -i -c echo  0.06s user 0.08s system 84% cpu 0.173 total