nvm: Loading nvm is unbelievably slow (7-46 seconds)

I’ve been using nvm for quite some time now and I recently installed it on a new laptop running Ubuntu 16.04. I’ve been experiencing extremely high load times: between 7 and 46 seconds on both zsh (my primary shell) as well as bash.

Here’s the output of nvm debug (I had chsh-ed to try bash):

nvm --version: v0.32.0
$SHELL: /bin/bash
$HOME: /home/vivek
$NVM_DIR: '$HOME/.nvm'
$PREFIX: ''
$NPM_CONFIG_PREFIX: ''
nvm current: v6.7.0
which node: $NVM_DIR/versions/node/v6.7.0/bin/node
which iojs: iojs not found
which npm: $NVM_DIR/versions/node/v6.7.0/bin/npm
npm config get prefix: $NVM_DIR/versions/node/v6.7.0
npm root -g: $NVM_DIR/versions/node/v6.7.0/lib/node_modules

I tried rm -rf ~/.nvm and reinstalled, but there was no improvement. I downgraded to 0.31.7 and saw some improvement - most load times were around 7 seconds now.

Please let me know whether there are some additional debugging steps that might help - I really can’t believe that loading nvm could be this slow without something messing around!

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 13
  • Comments: 31 (12 by maintainers)

Most upvoted comments

Try changing the line in your profile that sources nvm to something like . "$NVM_DIR/nvm.sh" --no-use - does that speed it up?

I made a dynamic NVM loader to speed things up. This way we don’t run the NVM loader code every time we open a new terminal window.

#!/bin/zsh
# ~/loadnvm.sh

#delete the aliases
unalias nvm
unalias npm
unalias node

#(this is the loader code nvm put in my .bashrc)
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 then in .zshrc (or .bashrc)

# nvm
alias nvm='. ~/loadnvm.sh; nvm "$@"'
alias npm='. ~/loadnvm.sh; npm "$@"'
alias node='. ~/loadnvm.sh; node "$@"'

You could even put this script in your .nvm directory if you don’t want it cluttering your $HOME.

EDIT: I added aliases for npm and node as well

Don’t forget npx, and all the global packages installed in your default node version. Also iojs if it’s v1-v3.

I’ve filed the issue at npm/npm#14458.

https://github.com/nylen/dotfiles/commit/33bb4a8332aff88ed7d74584b7bc2a9225f79deb / https://github.com/nylen/dotfiles/commit/cdb850873823bacc1662220b8e276c06f58fc6f1 also works for me and doesn’t require any modifications to nvm code.

Before these changes, initializing nvm takes about 6 seconds on a primed page cache and 15 seconds on a non-primed cache. After, 1 second and 3 seconds respectively [edit: fixed measurements].

For me, personally, the performance improvement is dramatic and well worth the trade-offs.

The approach in https://github.com/creationix/nvm/pull/1737 works well for me.

Sure. The prefix is what determines npm root -g, ie, where npm installs global modules and links. nvm requires that location be inside its own version dirs, and is incompatible with that setting.

Many people have it set from following ill-advised tutorials, for example. By adding these checks, a very very large number of monthly bug reports stopped coming in.

Basically, it’s doing npm config get prefix, and then if that location isn’t inside the nvm version dir, it errors out.

Oh and thanks a lot for confirming that this hardcoding solution will work for now! 😃

Last boot, loading nvm took about 8 seconds. I ran zmodload zsh/zprof before loading nvm, and then ran zprof to get the profiling output. The results are in a gist here: https://gist.github.com/polybuildr/26d7fafdac767b8c9a83d5a9de509260

I haven’t analyzed the output much yet (will try again in a couple of days), but just the zprof output might be useful.

Right, that definitely makes more sense. 😛

I’m busy the next couple of days, but after that, I’ll try to profile stuff and let you know how that goes.