Powerlevel9k: Very slow in home folder because of VCS prompt segment

Created on 8 Apr 2016  Â·  23Comments  Â·  Source: Powerlevel9k/powerlevel9k

I turned my home-folder ~ into a dotfiles repository with a lot of untracked files.
Ever since I made this change zsh is unusable slow while I'm located in the home-folder. It takes like 5-10 seconds to register keystrokes or execute anything.

Since I like the VCS segment I'd like to know what I can do about it without removing it entirely? Can I disable it in certain folders or is there some git function I can use?

Most helpful comment

I've made the RPROMPT async based on this blog post. You can see the changes at https://github.com/bhilburn/powerlevel9k/compare/master...andjscott:master if interested.

asciicast

All 23 comments

What I do is I make a ~/dotfiles repo and have a makefile in there that symlinks ~/.file to ~/dotfiles/file if they don't already exist. e.g. ~/.bashrc is a symlink to ~/dotfiles/bashrc, etc.

@dj-hedgehog Thanks for the report.

The way @jguenther suggests would work. But I don't like it that this theme slows your terminal that much down. So I create a repository with 500.000 untracked files, and voilá it is slow as hell.
For now I can say that it has to do with the checking of untracked files. If I deactivate this (currently only available on the next branch) by setting POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-aheadbehind git-stash git-remotebranch git-tagname) (notice that I took out git-untracked). This is no real solution, as it deactivates the whole checking of untracked files for all repositories.
I need to investigate this further. Just wanted to inform you about my ongoings.

Bad news: This is an issue of git itself. My first thought was, to cut off the response of git (with tail -n 1), but git computes the whole list of files before handing over to tail.. Second thought was to add an .gitignore with all untracked files in it (or a *), but git needs to check each file against this mask (which is slow). There seems no way to get just a boolean value out of git to know if there is an untracked file at all.
Even other commands than git status are not fast enough (like git ls-files, as suggested here). @sindresorhus did a benchmark of git commands.

IMHO there are two ways that would work:

  1. as @jguenther suggested, clone your dotfiles repository to another location, and link all relevant files to your home directory.
  2. do the vcs call asynchronously. Like the pure guys did. But that would be a major refactoring of the code.
  3. disable the untracked files checking in your home directory. To do so, you could add piece of code in your .zshrc: This would not work, as your .zshrc does not get re-evaluated every time. You could add a precmd instead.

zsh if [[ $(print -P "%~") == '~' ]]; then POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-aheadbehind git-stash git-remotebranch git-tagname) fi

But apart from that, all we could do is sending a patch to git..
Sorry.

@dritter - What are your thoughts on moving the dirty check into a precmd? It seems like that might speed up the responsiveness of the re-draw, if I'm understanding how it works correctly?

Hmm. The only way how I imagine these precmds are executed are:

  1. right before the prompt is printed. Then it will make no difference to executing this function as vcs_info-hook
  2. less often. This would make a difference, but will give us not enough information (the underlying repo might have changed in the meantime).

I think there is no faster way than doing it like we do (except for the async way). Best would be submitting a PR to git, adding a new command that will stop right after a valid (considering the .gitignore) untracked file was found.

@dritter - Thanks for the thoughts!

Hm... maybe I'll look into what it would take to do that check asynchronously, as the project did in your link. That would be pretty cool, but it sounds like the workload might be... heavy.

@dritter
On my computer it seems that both "symlinks" and "modify.zshrc" ways don't work at all.

@chenjuntong This is strange. Do you have a huge repository as well? Or does this happen in any repository (even small ones)?
And do you operate on a network-mounted folder?

@dritter This happen in any repository.When using powerlevel9k, the entire zsh seems slow down. Even simple command like "cd" is slower too. Extremely slow when using vcs. Therefore whether I operate on local folders(which I operate on) or network-mounted folders it is the same.

@chenjuntong That is strange. The vcs segment uses ZSHs VCS_INFO which does massively disk operations. So the vcs segment should be significantly faster on local folders than on network mounts..

Are your repositories git or mercurial ones? (Git should be faster than mercurial).

And how fast is the invocation of time git status or time hg st in your repo (with disabled vcs of course)? If the pure command is slow, this is something we cannot do anything about..

@dritter My repositories are git ones.
Here is the time git status.Seems fast.

When I disable vcs,every command becomes fast as usual.Therefore I guess the problem is on vcs.
Thanks for your patience.

Yeah, there seem to be some speed issues with ZSH's VCS_INFO submodule. As @dritter said before, the only way we might be able to get around this is to force some things to run asynchronously to the prompt draw. I haven't had a chance to look into this, yet, but would like to.

If anyone else is interested in contributing on this front, I consider this to be an important effort.

I've made the RPROMPT async based on this blog post. You can see the changes at https://github.com/bhilburn/powerlevel9k/compare/master...andjscott:master if interested.

asciicast

@andjscott I am sorry that this solution hasn't completely solve the problem. It maybe a little faster than the original config. Still, every command slower when using the VCS_INFO.

powerlevel9k_prepare_prompts gets called twice currently due to the zle-line-init and the precmd hooks. Is there a reason for this? The prompt seems to work fine without the zle-line-init hook.

@andjscott Only accidental. :D We had some trouble getting the vi_mode to work. The bug was introduced at this time..

Btw. the async prompt looks awesome! Thank you very much!

Work continues in #263...

@chenjuntong try brew install git
Had the same issue, my terminal was extremely slow after installing the powerlevel9k theme, and spent hours trying to get it solved until I hit brew install git to override the default git that was shipped with my OSX.
brew install git worked just fine for me.

@andela-oadesanya - Wow, really? Do you know what version ships with OSX by default, and what version of git you have now?

@bhilburn Apple ships git version 2.7.4 (Apple Git-66) on El Capitan (10.11.5).

Closing this to continue async work in #263 and vcs speedup work in #287.

@andjscott @andela-oadesanya @bhilburn "removing-zle-functions: https://github.com/bhilburn/powerlevel9k/tree/removing-zle-funcs" has solved this problem. Thank you!

@chenjuntong - Happy to hear that! We'll get that merged into master soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

OATOMO picture OATOMO  Â·  4Comments

mingrammer picture mingrammer  Â·  4Comments

DanielChabrowski picture DanielChabrowski  Â·  3Comments

edwardsmit picture edwardsmit  Â·  3Comments

davidmpaz picture davidmpaz  Â·  3Comments