Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NVM getting very slow on startup in Bash #1277

Closed
arndeash opened this issue Oct 29, 2016 · 193 comments
Closed

NVM getting very slow on startup in Bash #1277

arndeash opened this issue Oct 29, 2016 · 193 comments

Comments

@arndeash
Copy link

@arndeash arndeash commented Oct 29, 2016

I love NVM, but I've noticed that NVM is getting really slow during startup. See attached screenshot for what I mean: http://take.ms/LPOv3

Is this a bug or is something wrong on my Mac?

@ljharb
Copy link
Member

@ljharb ljharb commented Oct 29, 2016

What's nvm ls and nvm debug print out?

@ljharb
Copy link
Member

@ljharb ljharb commented Oct 29, 2016

You can also try adding --no-use to the end of the second nvm line (the one doing the sourcing) to confirm that it's the auto-use code path that's being slow.

@arndeash
Copy link
Author

@arndeash arndeash commented Oct 31, 2016

@ljharb
Adding --no-use makes it superfast, but then it doesnt load node. But I guess it confirms that the auto-use code path is slow. Here are the nvm ls and nvm debug

nvm ls
->       v6.9.1
default -> 6.9.1 (-> v6.9.1)
node -> stable (-> v6.9.1) (default)
stable -> 6.9 (-> v6.9.1) (default)
iojs -> N/A (default)
lts/* -> lts/boron (-> v6.9.1)
lts/argon -> v4.6.1 (-> N/A)
lts/boron -> v6.9.1
nvm debug
nvm --version: v0.32.1
$SHELL: /bin/bash
$HOME: /Users/Andreas
$NVM_DIR: '$HOME/.nvm'
$PREFIX: ''
$NPM_CONFIG_PREFIX: ''
nvm current: v6.9.1
which node: $NVM_DIR/versions/node/v6.9.1/bin/node
which iojs:
which npm: $NVM_DIR/versions/node/v6.9.1/bin/npm
npm config get prefix: $NVM_DIR/versions/node/v6.9.1
npm root -g: $NVM_DIR/versions/node/v6.9.1/lib/node_modules
@ljharb
Copy link
Member

@ljharb ljharb commented Oct 31, 2016

Do you have a .nvmrc file anywhere, like ~/.nvmrc?

@arndeash
Copy link
Author

@arndeash arndeash commented Oct 31, 2016

@ljharb the one line I have in that file is
onload-script=npm-autoinit/autoinit

Tried to remove it, didn't make any difference, so added it back.

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 1, 2016

@ahennie in a file called nVmrc, you have that line?

Can you provide a little more info on your Mac? Do you have an SSD, how old is it, how fast/much RAM, etc?

@mitermayer
Copy link

@mitermayer mitermayer commented Nov 2, 2016

This is also very slow for me on gentoo linux.

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 2, 2016

@mitermayer can you also go through the same steps above and see if you get the same or different results?

@arndeash
Copy link
Author

@arndeash arndeash commented Nov 3, 2016

@ljharb Sorry, that was .nPmrc. I don't have a .nVmrc-file. It must be sw, not hw related. I got Macbook Pro 15" i7, 16gb RAM, SSD. What could it be?

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 3, 2016

@ahennie that should be fast enough. Basically it's that nvm use calls into npm config get prefix, which is very slow. I'll keep looking into it.

@arndeash
Copy link
Author

@arndeash arndeash commented Nov 4, 2016

@ljharb thanks. it wasnt slow like this earlier. does the number of global modules affect the speed? other things I can do to speed it up?

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 4, 2016

When you say "earlier" do you mean on an earlier version, before I was doing prefix checking? Or do you mean on the same version of nvm?

@carlosjs23
Copy link

@carlosjs23 carlosjs23 commented Nov 5, 2016

same issue too.

@arndeash
Copy link
Author

@arndeash arndeash commented Nov 7, 2016

@ljharb it's hard to say. I installed nvm months ago, but never really used node. However loading the bash has always been fast. I have been coding node a lot more lately, including installing a few global modules, and it suddenly have gotten slower. I also updated to the newest version of nvm, npm and node. Deleted a few global modules now, but it's still slow. So I think the slowness was intruduced in any of the updates.

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 7, 2016

It's likely the npm config get prefix call then.

@arndeash
Copy link
Author

@arndeash arndeash commented Nov 8, 2016

@ljharb suddenly it's faster again. don't know why. but I thought you should know, before you spend to much time on it.

@ryankask
Copy link

@ryankask ryankask commented Nov 10, 2016

I just checked out the latest tag and noticed this. I forget what tag I was previously using but it was in the v0.31 series.

Adding the the --no-use fixes the issue.

@Nick011
Copy link

@Nick011 Nick011 commented Nov 23, 2016

Experiencing the same problem. Everything was fine until I upgraded OSX to Sierra a few days ago. Ran brew update and brew upgrade, but it's still slow. --no-use Makes it better, but still slightly slower than what it was before I upgraded.

When I run nvm ls It takes about 2-3 seconds to start, then lists everything down to system then takes 2-3 seconds for every alias after that. Here is my output:

➜  ~ nvm ls
        v5.10.1
         v6.1.0
         v6.6.0
->       v6.9.1
         system
default -> v6.9.1
node -> stable (-> v6.9.1)
stable -> 6.9 (-> v6.9.1) (default)
iojs -> iojs- (-> system) (default)
lts/* -> lts/boron (-> v6.9.1)
lts/argon -> v4.6.2 (-> N/A)
lts/boron -> v6.9.1

I'm running a 2013 15in macbook pro. 2.7Ghz, 16GB RAM.
I'm using iterm2 and oh-my-zsh, but saw someone else here had the same problem with bash.

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 24, 2016

@Nick011 nvm is not supported via homebrew (the homebrew formula says this when you install it). If you brew uninstall nvm, and then install it properly via the curl script in the readme, my suspicion is that it will go much faster.

@nico1510
Copy link

@nico1510 nico1510 commented Nov 25, 2016

same issue here... --no-use fixes it but also fails to load node

@ljharb
Copy link
Member

@ljharb ljharb commented Nov 25, 2016

@nico1510 right, the npm config get prefix call that nvm is making when running nvm use is the slowest part. I don't yet have a solution to speed that up.

@martinheidegger
Copy link

@martinheidegger martinheidegger commented Dec 6, 2016

To investigate the performance issues myself, I tried to setup some performance logging in a forked branch:
https://github.com/martinheidegger/nvm/tree/debug/performance

and I also come to the conclusion that the biggest issue is starting node. (npm config get prefix is a node script, as opposed to all the other scripts).

@ljharb
Copy link
Member

@ljharb ljharb commented Dec 6, 2016

@martinheidegger i think you're spot on. If anyone can come up with a way to perfectly emulate npm config get prefix without invoking node (especially if it can be PRred into npm itself so that they'll keep it up to date), that would likely erase most people's performance issues.

@martinheidegger
Copy link

@martinheidegger martinheidegger commented Dec 6, 2016

@ljharb I ran another test for the performance of npm config get prefix and it seems to have not changed much over the versions: https://gist.github.com/martinheidegger/32d00e90e0163a22a4ffc78df796001e

I opened npm/npm#15149 added comments to npm/npm#14458 (comment) in order to let the npm team know of this problem as well (with some extended info).

@martinheidegger
Copy link

@martinheidegger martinheidegger commented Dec 13, 2016

I opened nodejs/help#396 in order to figure out if Node.js and NPM could share the same logic in order for nvm to not need to rely on Node and/or make NPM faster.

Quoting:

If npm wanted to use that, they should file an issue or pull request to make it public API.

I guess same can be said of nvm?

@SrBrahma
Copy link

@SrBrahma SrBrahma commented Apr 24, 2020

I use this solution:

https://www.reddit.com/r/node/comments/4tg5jg/lazy_load_nvm_for_faster_shell_start/d5ib9fs/

Works well on zsh. For some reason, on bash I get some errors.

byronsanchez added a commit to byronsanchez/dotfiles that referenced this issue Apr 25, 2020
Lazy-Load NVM - Sourcing NVM directly takes about 0.5s, which actually
slows down terminal initialization and is noticeable. I'll try different
permutations if I encounter different roadblocks due to the use of
lazy-loading. Otherwise, I'll stick to the first thing that works and is
easier to reason about.

Links:

- nvm-sh/nvm#782
- https://www.growingwiththeweb.com/2018/01/slow-nvm-init.html
- nvm-sh/nvm#1277 (comment)
- https://gist.github.com/gfguthrie/9f9e3908745694c81330c01111a9d642
- https://www.reddit.com/r/node/comments/4tg5jg/lazy_load_nvm_for_faster_shell_start/d5ib9fs/
bengillies added a commit to bengillies/homedir that referenced this issue May 14, 2020
Running this in .zshrc was causing a >5 second slowdown every time a new
shell was spawned.

This solution was taken from
nvm-sh/nvm#1277 (comment)
and just links the correct version of node statically, which is really
what nvm should be doing anyway, meaning no startup time.

This requires running `nvm alias default <version number>` to ensure
that a version number is present in the nvm default file.

nvm is still available by running nvm.sh the first time you call it
@grisaitis
Copy link

@grisaitis grisaitis commented May 27, 2020

The directory in the last line can be replaced with $NVM_DIR:

export NVM_DIR="$HOME/.nvm"
[ -s "/usr/local/opt/nvm/etc/bash_completion" ] && . "/usr/local/opt/nvm/etc/bash_completion"
export PATH="$NVM_DIR/versions/node/v$(<$NVM_DIR/alias/default)/bin:$PATH"
alias nvm="unalias nvm; [ -s $NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; nvm $@"

@char101 is there a typo in the last line?

i think there's a missing " in [ -s $NVM_DIR/nvm.sh" ]

the last line should be:

alias nvm="unalias nvm; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; nvm $@"

thank you otherwise!! very useful.

@char101
Copy link

@char101 char101 commented May 27, 2020

@char101 is there a typo in the last line?

Thank you for the correction, the missing quote has been added.

@ledenis
Copy link

@ledenis ledenis commented Aug 17, 2020

export PATH="$NVM_DIR/versions/node/v$(<$NVM_DIR/alias/default)/bin:$PATH"

It does not work for me because it has an additional v, which gives me this in my $PATH: /home/xxxx/.nvm/versions/node/vv10.22.0/bin. I had to remove the v:

export PATH="$NVM_DIR/versions/node/$(<$NVM_DIR/alias/default)/bin:$PATH"
@ljharb

This comment has been hidden.

@SrBrahma

This comment was marked as spam.

@ledenis

This comment has been hidden.

@ljharb

This comment has been hidden.

eudika added a commit to eudika/prezto that referenced this issue Aug 28, 2020
$NVM_DIR/nvm.sh is a slow script and has doubled time to load zsh.
In this commit, the script is not loaded until required.
cf. nvm-sh/nvm#1277
eudika added a commit to eudika/prezto that referenced this issue Aug 30, 2020
$NVM_DIR/nvm.sh is a slow script and has doubled time to load zsh.
In this commit, the script is not loaded until required.
cf. nvm-sh/nvm#1277
@king-11
Copy link

@king-11 king-11 commented Sep 16, 2020

this code snippet has really used my startup time while ensuring that I also have access to global packages as well as yarn globals and yarn project have same node env version.

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

NODE_GLOBALS=(`find ~/.nvm/versions/node -maxdepth 3 -type l -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`)
NODE_GLOBALS+=(node nvm yarn)

_load_nvm() {
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
}

for cmd in "${NODE_GLOBALS[@]}"; do
eval "function ${cmd}(){ unset -f ${NODE_GLOBALS[*]}; _load_nvm; unset -f _load_nvm; ${cmd} \$@; }"
done
unset cmd NODE_GLOBALS

export PATH="$PATH:$HOME/.yarn/bin"```
@milahu

This comment has been hidden.

@ljharb

This comment has been hidden.

@milahu

This comment was marked as disruptive content.

@ljharb

This comment has been hidden.

@milahu

This comment has been hidden.

@ljharb

This comment has been hidden.

@milahu

This comment has been hidden.

@ljharb
Copy link
Member

@ljharb ljharb commented Oct 8, 2020

For future reference, nvm supports mostly POSIX shells - ksh, dash, sh, bash, zsh in particular.

@tilsmen
Copy link

@tilsmen tilsmen commented Oct 8, 2020

@milahu This was implemented long time ago already, together with other improvements. However it never got merged due to reasons you can read yourself, thought it might be worth mentioning. There is a hard fork which is fast and also does this caching. Here is the reasoning and the hard fork, I am using that one for very long time and didn't had any problems with it wzrdtales/nvm-ng#2

Don't forget the --fast-reuse flag to activate this fast path.

@milahu

This comment was marked as disruptive content.

@ljharb

This comment has been hidden.

@ljharb
Copy link
Member

@ljharb ljharb commented Oct 8, 2020

@tilsmen Careful using any forks; that one's missing over 2 years of improvements.

@tilsmen
Copy link

@tilsmen tilsmen commented Oct 9, 2020

yes i know @ljharb but nothing really meaningful was added (for my terms, not in general don't get me wrong not trying to offend here) during this 2 years. The difference of the hard fork and your original are just two commits in the hard fork which are like a show stopper to me from your work. Everything is working with this fork also with the newest node version without any flaw and I have the benefit of not being disturbed in my workflow and still able to use my console normal. So I think it is reasonable, if you by any chance improve here the loading times let me know though.

@ljharb
Copy link
Member

@ljharb ljharb commented Oct 9, 2020

@tilsmen luckily i'm very close to releasing a performance improvement here - i've just opened #2317. if you could try that out locally and comment on the PR with performance comparisons, that would be very helpful.

@revolter

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.