nvm: nvm very slow to start
Operating system and version:
nvm debug
output:
nvm --version: v0.38.0
$TERM_PROGRAM: iTerm.app
$SHELL: /bin/zsh
$SHLVL: 1
whoami: 'some-user'
${HOME}: /Users/some-user
${NVM_DIR}: '${HOME}/.nvm'
${PATH}: ${NVM_DIR}/versions/node/v16.13.2/bin:${HOME}/.rbenv/bin:${HOME}/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:${HOME}/Library/Android/sdk/emulator:${HOME}/Library/Android/sdk/tools:${HOME}/Library/Android/sdk/tools/bin:${HOME}/Library/Android/sdk/platform-tools
$PREFIX: ''
${NPM_CONFIG_PREFIX}: ''
$NVM_NODEJS_ORG_MIRROR: ''
$NVM_IOJS_ORG_MIRROR: ''
shell version: 'zsh 5.8 (x86_64-apple-darwin20.0)'
uname -a: 'Darwin 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64'
checksum binary: 'shasum'
OS version: macOS 11.5.2 20G95
curl: /usr/bin/curl, curl 7.64.1 (x86_64-apple-darwin20.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.41.0
wget: not found
sed: /usr/bin/sed
cut: /usr/bin/cut
basename: /usr/bin/basename
rm: /bin/rm
mkdir: /bin/mkdir
xargs: /usr/bin/xargs
git: /usr/local/bin/git, git version 2.31.0
grep: /usr/bin/grep, grep (BSD grep) 2.5.1-FreeBSD
awk: /usr/bin/awk, awk version 20200816
nvm current: v16.13.2
which node: ${NVM_DIR}/versions/node/v16.13.2/bin/node
which iojs: iojs not found
which npm: ${NVM_DIR}/versions/node/v16.13.2/bin/npm
npm config get prefix: ${NVM_DIR}/versions/node/v16.13.2
npm root -g: ${NVM_DIR}/versions/node/v16.13.2/lib/node_module
nvm ls
output:
v14.18.3
v16.1.0
-> v16.13.2
default -> 14 (-> v14.18.3)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.13.2) (default)
stable -> 16.13 (-> v16.13.2) (default)
lts/* -> lts/gallium (-> v16.13.2)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.9 (-> N/A)
lts/fermium -> v14.18.3
lts/gallium -> v16.13.2
How did you install nvm
?
The bash script from the README. I also have the zsh shell extension from the README to automatically run nvm use
on each directory change.
What steps did you perform?
Create a new iTerm tab or pane
What happened?
It’s very slow to start every time
I’ve followed these steps to get some zsh profiling output, this is what it looks like:
Found '/Users/some-user/some-folder/some-repo/.nvmrc' with version <16>
Now using node v16.13.2 (npm v8.1.2)
num calls time self name
-----------------------------------------------------------------------------------
1) 4 10828.88 2707.22 55.01% 6985.65 1746.41 35.49% nvm
2) 1 11108.00 11108.00 56.43% 6012.77 6012.77 30.54% nvm_auto
3) 2 3506.05 1753.03 17.81% 3311.19 1655.59 16.82% nvm_ensure_version_installed
4) 1 8514.78 8514.78 43.25% 2781.13 2781.13 14.13% load-nvmrc
5) 2 194.86 97.43 0.99% 194.86 97.43 0.99% nvm_is_version_installed
6) 2 202.59 101.30 1.03% 162.91 81.46 0.83% nvm_die_on_prefix
7) 1 125.08 125.08 0.64% 119.30 119.30 0.61% nvm_rc_version
8) 2 37.65 18.83 0.19% 37.65 18.83 0.19% compaudit
9) 4 36.83 9.21 0.19% 36.83 9.21 0.19% nvm_grep
10) 1 62.11 62.11 0.32% 24.45 24.45 0.12% compinit
11) 2 14.20 7.10 0.07% 14.20 7.10 0.07% nvm_echo
12) 8 39.68 4.96 0.20% 2.84 0.36 0.01% nvm_npmrc_bad_news_bears
13) 2 1.05 0.53 0.01% 1.05 0.53 0.01% nvm_has
14) 1 0.39 0.39 0.00% 0.39 0.39 0.00% add-zsh-hook
15) 1 0.09 0.09 0.00% 0.09 0.09 0.00% compdef
16) 1 0.18 0.18 0.00% 0.08 0.08 0.00% complete
17) 1 11108.06 11108.06 56.43% 0.06 0.06 0.00% nvm_process_parameters
18) 1 0.04 0.04 0.00% 0.04 0.04 0.00% nvm_is_zsh
19) 1 0.04 0.04 0.00% 0.04 0.04 0.00% nvm_is_iojs_version
20) 1 0.02 0.02 0.00% 0.02 0.02 0.00% bashcompinit
-----------------------------------------------------------------------------------
17) 1 11108.06 11108.06 56.43% 0.06 0.06 0.00% nvm_process_parameters
1/1 11108.00 11108.00 56.43% 6012.77 6012.77 nvm_auto [2]
-----------------------------------------------------------------------------------
1/1 11108.00 11108.00 56.43% 6012.77 6012.77 nvm_process_parameters [17]
2) 1 11108.00 11108.00 56.43% 6012.77 6012.77 30.54% nvm_auto
1/4 5095.23 5095.23 25.88% 41.58 41.58 nvm [1]
-----------------------------------------------------------------------------------
2/4 10760.61 5380.31 54.66% 6917.38 3458.69 nvm [1]
1/4 5733.65 5733.65 29.13% 26.69 26.69 load-nvmrc [4]
1/4 5095.23 5095.23 25.88% 41.58 41.58 nvm_auto [2]
1) 4 10828.88 2707.22 55.01% 6985.65 1746.41 35.49% nvm
1/1 0.04 0.04 0.00% 0.04 0.04 nvm_is_iojs_version [19]
2/2 1.05 0.53 0.01% 1.05 0.53 nvm_has [13]
1/2 8.41 8.41 0.04% 8.41 8.41 nvm_echo [11]
1/1 125.08 125.08 0.64% 119.30 119.30 nvm_rc_version [7]
2/2 202.59 101.30 1.03% 162.91 81.46 nvm_die_on_prefix [6]
2/2 3506.05 1753.03 17.81% 3311.19 1655.59 nvm_ensure_version_installed [3]
2/4 10760.61 5380.31 54.66% 6917.38 3458.69 nvm [1]
-----------------------------------------------------------------------------------
4) 1 8514.78 8514.78 43.25% 2781.13 2781.13 14.13% load-nvmrc
1/4 5733.65 5733.65 29.13% 26.69 26.69 nvm [1]
-----------------------------------------------------------------------------------
2/2 3506.05 1753.03 17.81% 3311.19 1655.59 nvm [1]
3) 2 3506.05 1753.03 17.81% 3311.19 1655.59 16.82% nvm_ensure_version_installed
2/2 194.86 97.43 0.99% 194.86 97.43 nvm_is_version_installed [5]
-----------------------------------------------------------------------------------
2/2 202.59 101.30 1.03% 162.91 81.46 nvm [1]
6) 2 202.59 101.30 1.03% 162.91 81.46 0.83% nvm_die_on_prefix
8/8 39.68 4.96 0.20% 2.84 0.36 nvm_npmrc_bad_news_bears [12]
-----------------------------------------------------------------------------------
2/2 194.86 97.43 0.99% 194.86 97.43 nvm_ensure_version_installed [3]
5) 2 194.86 97.43 0.99% 194.86 97.43 0.99% nvm_is_version_installed
-----------------------------------------------------------------------------------
1/1 125.08 125.08 0.64% 119.30 119.30 nvm [1]
7) 1 125.08 125.08 0.64% 119.30 119.30 0.61% nvm_rc_version
1/2 5.79 5.79 0.03% 5.79 5.79 nvm_echo [11]
-----------------------------------------------------------------------------------
10) 1 62.11 62.11 0.32% 24.45 24.45 0.12% compinit
1/2 37.65 37.65 0.19% 0.74 0.74 compaudit [8]
-----------------------------------------------------------------------------------
8/8 39.68 4.96 0.20% 2.84 0.36 nvm_die_on_prefix [6]
12) 8 39.68 4.96 0.20% 2.84 0.36 0.01% nvm_npmrc_bad_news_bears
4/4 36.83 9.21 0.19% 36.83 9.21 nvm_grep [9]
-----------------------------------------------------------------------------------
1/2 37.65 37.65 0.19% 0.74 0.74 compinit [10]
1/2 36.91 36.91 0.19% 36.91 36.91 compaudit [8]
8) 2 37.65 18.83 0.19% 37.65 18.83 0.19% compaudit
1/2 36.91 36.91 0.19% 36.91 36.91 compaudit [8]
-----------------------------------------------------------------------------------
4/4 36.83 9.21 0.19% 36.83 9.21 nvm_npmrc_bad_news_bears [12]
9) 4 36.83 9.21 0.19% 36.83 9.21 0.19% nvm_grep
-----------------------------------------------------------------------------------
1/2 8.41 8.41 0.04% 8.41 8.41 nvm [1]
1/2 5.79 5.79 0.03% 5.79 5.79 nvm_rc_version [7]
11) 2 14.20 7.10 0.07% 14.20 7.10 0.07% nvm_echo
-----------------------------------------------------------------------------------
2/2 1.05 0.53 0.01% 1.05 0.53 nvm [1]
13) 2 1.05 0.53 0.01% 1.05 0.53 0.01% nvm_has
-----------------------------------------------------------------------------------
14) 1 0.39 0.39 0.00% 0.39 0.39 0.00% add-zsh-hook
-----------------------------------------------------------------------------------
16) 1 0.18 0.18 0.00% 0.08 0.08 0.00% complete
1/1 0.09 0.09 0.00% 0.09 0.09 compdef [15]
-----------------------------------------------------------------------------------
1/1 0.09 0.09 0.00% 0.09 0.09 complete [16]
15) 1 0.09 0.09 0.00% 0.09 0.09 0.00% compdef
-----------------------------------------------------------------------------------
18) 1 0.04 0.04 0.00% 0.04 0.04 0.00% nvm_is_zsh
-----------------------------------------------------------------------------------
1/1 0.04 0.04 0.00% 0.04 0.04 nvm [1]
19) 1 0.04 0.04 0.00% 0.04 0.04 0.00% nvm_is_iojs_version
-----------------------------------------------------------------------------------
20) 1 0.02 0.02 0.00% 0.02 0.02 0.00% bashcompinit
What did you expect to happen?
I expected it to load faster
Is there anything in any of your profile files that modifies the PATH
?
There’s a few things being added for android development, ANDROID_HOME
, JAVA_HOME
, etc
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 47
- Comments: 31 (8 by maintainers)
Commits related to this issue
- Lazy load nvm https://github.com/nvm-sh/nvm/issues/2724#issuecomment-1336537635 — committed to raineorshine/dotfiles by raineorshine a year ago
A lazy loading approach can be used as a work around if you’re seeing lag before the prompt becomes usable. The following can be added to your
.zshrc
(or.*rc
):For anyone else finding this after reading the blog posts lately about measuring ZHS startup times:
My shell took just over 300ms to start, as measured by hyperfine. I commented out the nvm part and it dropped down to around 45ms.
I googled around and found fnm, which seems to be a port of
nvm
to Rust. After adding fnm to my.zshrc
, and installing the same Node.js version I already before via nvm, I measured my shell startup time as 51ms.My conclusion: for now I will replace
nvm
withfnm
which seems to be a drop in replacement but with a 40x speedup 🐎I’m not sure if this is a “performance issue”, so I’m a bit hesitant to open a new issue. ~300ms shell startup is probably fine for a lot of people, and I’m not sure that this could be fixed in nvm without switching to a complied language. But if you think that this can be improved and want any more measurements or insight I’m happy to help!
Thanks for linking this! I ended up needing to make a few changes, if anyone else runs into hiccups:
yes, advertising other projects in any repo is quite unwelcome, and isn’t a workaround for those who wish to keep using the same project.
PRs to improve specific slow places are appreciated. This kind of profiling output is also very helpful, since it helps highlight what needs work.
Note that any lazy loading approach has some caveats; namely that any global packages you have installed won’t be available until the first time you run
nvm
,npm
, ornode
.this plugin makes loading of nvm zsh functions lazy https://github.com/lukechilds/zsh-nvm (on my machine >800ms -> ~40ms)
works great and has some interesting options; … however it has not seen the update for nearly 2 years
it would be a good course of action to incorporate the logic from that script into this one
@LinusU @abejfehr - this is what I had suggested but it was marked as spam
If anyone is interested, I have made it so it lazy loads on cmd run. I haven’t found a solution like this one yet but I know it is a combination of the solutions from above.
I’ve done a bit of digging and there seems to be a lot of custom logic (and therefore additional complexity) to support “iojs”.
I might be being naive, but does anyone even use iojs? Their website looks like it was updated semi-recently, but they seem to mention that nvm doesn’t support it yet (when it has for 7 years!):
I’ve deleted anything pertaining to “iojs” from my
nvm.sh
file and it seems to be running a bit faster too.Would this project be interested in a PR to remove iojs support?
Edit: I just noticed that the link to io.js’ repo from nvm’s README file just redirects to node’s repo now
I think for those who still want to use
nvm
-proper then it is important that a lazy loading option be integrated into the trunk. I personally am hesitant to use Rust-based tools when I can avoid them as I personally like neither the ecosystem nor the language.And yes, advertising other projects is bad form in these places. Definitely a catch 22 since I can understand the desire to share your success and options, which is appreciated, but it can easily be seen as a slap to this project by those who invest such efforts and sacrifices to make it and keep it going… Humans are funny things.
Anyway, thanks to the developers of this project for your passion and sacrifice for such a tool.
This is my hack in the
.zshrc
.i want to disagree here too, i don’t consider it as advertisement, it literally solved my problem because it’s incredibly fast.
I just wanted to share that since this issue I’ve long since switched to mise and it’s very performant, and is essentially a drop-in replacement for nvm (for my purposes anyway)
Take into account that the lazy load approach breaks the LSP servers with nvim if nvm is not loaded previously. I have that problem, and running NVM at least one time before opening nvim solve it.
The plumbing for that is also needed to support node RCs and nightlies, so even if i wanted to remove it (i don’t - i have 300+ repos that test on it, which constitutes over 10% of npm’s download traffic that benefits from the support) i don’t think it’d end up making things faster since we still want to add RC support in particular.
I’d love a PR that made the existing feature set faster, of course 😃
Thank you @linorabolini for your suggestion. Given that
node
etc. andnvm
get very infrequent use from me since I mostly work with V and Ruby, having this to lighten up my load for shell load time is a wonderful help. Wish it would get mainline integration.I’ve since switched node version managers (
fnm
). Offering this as a workaround for folks seeking help and finding this issue.@lucasjohnston i’m the maintainer, and sure, either one is a great idea. PRs are welcome.
No, I don’t have any way to avoid fully loading nvm that avoids that caveat, which is the sole reason there’s no official mechanism to do that (or better, the sole reason it’s not just The Way nvm works)
The main culprit for me was the
load-nvmrc
function which runs every time a folder is opened. I did two things to simplify the steps taken:.nvmrc
file exists in the current directory, its parent (to a depth of 3), or in its immediate child. This is super quick so doesn’t slow down opening new directories, and meanscd
’ing into and out of directories will trigger an nvm change as expected.It’s not perfect, but it retains the majority of nvm’s primary features and stops me waiting forever for my shell to resolve.
Here’s my implementation:
The lazy loading approaches don’t work for me since I’m using the zsh hook that automatically runs
nvm use
on each directory change. I want my node version to be correct when I switch between directories because I have many projects that use many node versions.Edit: I just realized this also includes functions for
node
/npm
/etc and that looks like it’d work, so maybe I’ll try that.