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
Lazy load nvm #1186
Lazy load nvm #1186
Conversation
nvm takes on average half of a second to load, which is more than whole prezto takes to load. This can be noticed when you open a new shell. To avoid this, we are creating placeholder function for nvm, node, and all the node packages previously installed in the system to only load nvm when it is needed. This code is based on the scripts: * https://www.reddit.com/r/node/comments/4tg5jg/lazy_load_nvm_for_faster_shell_start/d5ib9fs * http://broken-by.me/lazy-load-nvm/ * nvm-sh/nvm#781 (comment)
|
||
for cmd in "${NODE_GLOBALS[@]}"; do | ||
# Skip defining the function if the binary is already in the PATH | ||
if ! which ${cmd} &>/dev/null; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I was wondering how you were going to handle package binaries like https://www.npmjs.com/package/which
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also trying #1178. Nodenv seems much faster on init and uses a different method for managing different node versions.
Since I already use rbenv which is much better than rvm and nodenv is a fork. I decided to give it a try.
Seems good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've had great success with nodenv
and started using it because I was also familiar with rbenv
. I too tried nvm
and also found it noticeably slowed down my shell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be improved by using $+commands[$cmd]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if you want any change I can update
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on what you're trying to do, is-callable
from the helper module or $+commands
would be preferable.
@sorin-ionescu Any chance this could get merged? :) before:
after:
|
I also run a custom fork solely so I can include this patch. |
This PR got merged in the community maintained fork of this repo. zsh-users is an organization dedicated to host Zsh community projects and therefore became the rational home for a community maintained version of prezto. Your contribution is greatly appreciated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few tweaks I'd like to see, but the general concept looks good.
NVM_DIR=$1 | ||
# Skip adding binaries if there is no node version installed yet | ||
if [ -d $NVM_DIR/versions/node ]; then | ||
NODE_GLOBALS=(`find $NVM_DIR/versions/node -maxdepth 3 \( -type l -o -type f \) -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be willing to bet that this doesn't work in either osx or linux. There should be a way to use extended glob syntax to do something like this but only use zsh internals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would be the part not working in OSX or Linux?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking a bit closer, it looks fine. I've just run into strange issues with find on linux and osx being incompatible.
for cmd in "${NODE_GLOBALS[@]}"; do | ||
# Skip defining the function if the binary is already in the PATH | ||
if ! which ${cmd} &>/dev/null; then | ||
eval "${cmd}() { unset -f ${cmd} &>/dev/null; [ -z \${NVM_LOADED+x} ] && load_nvm; ${cmd} \$@; }" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsetting this specific command and using NVM_LOADED shouldn't be needed because we unset all the functions in load_nvm anyway, so we don't need to track it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, because this is using eval, I'd feel a lot better if there was a way to know that the command names were sanitized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any suggestions?
Replaced |
What's the status on this? It doesn't look like there's been an update by the author more than a month after changes were requested. Does anyone else want to take this up? |
I completely missed this @belak. It will probably take me some days to update this. If you want to do it I added permissions for the owners to edit this pr. |
No worries. Thanks for the response! I don't know if I'll get to it soon either, so no rush. Just trying to follow up on a few loose ends. :) |
I'm hesitant about this, and I'm hoping @creationix would be willing to take a look before we merge this. I used to follow the That said, I don't work on any node projects right now, so haven't stayed up to date with |
There has been quite a bit of feature and code growth since I handed nvm over to a new maintainer. If you look at the contribution graph my initial implementation is a fraction of the overall code. If I were to write nvm again knowing what I now know, it would look a lot like nvs. https://github.com/jasongin/nvs There is no need to have all the heavy logic in shell. The only thing that has to be shell script is changing the current |
I'm afraid I don't know enough about the current nvm implementation to give good feedback on your lazy load approach. Good luck! |
Thanks for weighing in @creationix! I actually meant to tag the new maintainer, as he is the one whose comments I've seen and didn't realize he wasn't you... so tag @ljharb 😄 |
"code bloat" is pretty uncharitable; there's quite a lot of refactors, bug fixes, and POSIX robustness improvements in there :-) Lazy loading The only reason it's slow is because I'd be willing to bet that if you temporarily overwrote the |
Sorry, sometimes I forget the negative connotations with that phrase. You've done great work! |
Thanks for chiming in @ljharb, much appreciated |
nvm takes on average half of a second to load, which is more than whole prezto takes to load.
This can be noticed when you open a new shell.
To avoid this, we are creating placeholder function for nvm, node, and all the node packages previously installed in the system to only load nvm when it is needed.
This code is based on the scripts: