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 is slow (> 650ms) #1242

Closed
mkscrg opened this issue Sep 23, 2016 · 9 comments · Fixed by #2317
Closed

NVM is slow (> 650ms) #1242

mkscrg opened this issue Sep 23, 2016 · 9 comments · Fixed by #2317
Labels
performance This relates to anything regarding the speed of using nvm.

Comments

@mkscrg
Copy link

mkscrg commented Sep 23, 2016

I find myself running nvm unalias default after every nvm install, since it makes new shell creation so much faster. Here it is, with time source ~/.nvm/nvm.sh in ~/.bash_profile:

After nvm alias default node:
nvm_slow

After nvm unalias default:
nvm_fast

I spend enough time away from Node (and enough time in the shell) that remembering to nvm use is worth the hassle.

If an intrepid contributor wanted to make NVM faster, where might they start?

@ljharb
Copy link
Member

ljharb commented Sep 23, 2016

You can avoid the need to unalias by adding --no-use on the end of the line in your profile that does . "$NVM_DIR/nvm.sh".

There's two main things that make it slow right now - one is the npm config get prefix call, which I'm not sure how to speed up since that depends on npm (and there's a litany of ways npm can locate that prefix) - the other is locating the default alias.

I'd start by comparing the code paths with and without --no-use (when sourcing) and then profile the use steps.

@ljharb ljharb added the performance This relates to anything regarding the speed of using nvm. label Sep 23, 2016
@mkscrg
Copy link
Author

mkscrg commented Sep 23, 2016

Aha! --no-use is nice.

I'll take a look and report back 👍

@Kasahs
Copy link

Kasahs commented Oct 10, 2017

Hey guys! I wrote a simple app (kinda) called znvm that combines a bunch of solutions given over here for zsh users.
Features:

  • Make zsh with nvm faster by loading only if .nvmrc file found or called explicitly
  • Automatically calls nvm use if .nvmrc is present.
  • If node vesion in .nvmrv is not installed it will automatically call nvm install <node_version>
  • Can be configured to load nvm before certain commands are executed on the shell (such as editors and IDEs)

check it out: https://github.com/Kasahs/.znvm
Just follow the instructions to install
I hope it helps

@peternann
Copy link

peternann commented Nov 25, 2017

This 600ms or so delay on EVERY shell start was driving me mad too.
I figured out an alternative work-around:
I put the standard nvm config in my ~/.profile - So it only runs once (not every shell), and from what I glean above, this puts the 'default' node version in place for all following sub-shells... (Right?)

'node' and 'npm' themselves seem to work just fine with the nvm setup only in ~/.profile. So if you're happy to stick with the defaults, all is well.

But then I found "nvm" wouldn't work in shells started from the GUI desktop, because 'nvm' itself is a shell function and hence not exported through sub-shells.

So I came up with this dirty hack:
(Explanation in the comments)

# In ~/.profile include the usual - runs just once at login:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" 
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"

And then in ~/.bashrc:

# NVM setup is about the only thing in this script that takes any noticeable time to run.
# Which is not something you want in your .bashrc...
# So, we use a 'just in time' approach. Setup a function that loads the 'real' nvm on first
# use. Note that the 'nvm' function defined here gets over-ridden via sourcing nvm.sh:
# (So you get the ~600ms delay only on first use, in any shell)
export NVM_DIR="$HOME/.nvm"
function nvm() {
	[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" 
	[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
	nvm "$*"
}

Maybe it's not quite so 'dirty'... Seems to work like a charm...

@ljharb
Copy link
Member

ljharb commented Nov 26, 2017

@peternann the major downside there is that node, npm, and any global modules installed in your default node version won’t be available until after you’ve invoked nvm.

@peternann
Copy link

peternann commented Nov 26, 2017

@ljharb - As I mentioned in the post, that's not what I am observing - node, npm, etc work just fine, even before my nvm trigger function is ever run.

I've updated the message above to include the 2-parts of the approach, for abundant clarity.

I'm not 100% sure how nvm works, but I think running the setup once, in .profile/.bash_profile puts enough in place (in exported environment) for node/npm to run. Only 'nvm' itself has trouble (being a shell function and not usually exportable), thus the JIT code above.
(I also wondered about exporting all the nvm shell functions while in .profile, via bash's 'export -f', but didn't try it... - Seems like a large number of functions would need exporting)

@ljharb
Copy link
Member

ljharb commented Nov 26, 2017

@peternann ah, interesting - you're saying that the PATH gets inherited from .profile, just not the sourced nvm functions?

That seems like it might be an interesting solution, if it works across platforms.

@peternann
Copy link

peternann commented Nov 26, 2017

@ljharb Well, yes, PATH is definitely inherited safely by all sub-shells. The Unix world would fall into a heap if not... And yes, it's just functions (like nvm here) that are not reliably inherited. Like I said - The setup above is working like a charm for me.

@leonardosnt
Copy link

I wrapped the startup code inside a function like @peternann did, It's much better to get a ~600ms delay when you will actually use nvm instead of every time you open the terminal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance This relates to anything regarding the speed of using nvm.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants