powerlevel10k: Startup performance is noticeably slow
Hey @romkatv,
You have sparkled my interest in https://github.com/denysdovhan/spaceship-prompt/issues/734, so first of all thanks for that š
Iām very interested to give this prompt a try, so I installed it using antigen and followed the initial wizard to configure the prompt.
While the experience in general feels smooth, I noticed that the startup time is noticeably slower than what Iām used to with my async version of spaceship. I canāt give you any numbers, and to be honest I didnāt dig deeply into powerlevel configuration to see what can be optimized (I only tried to disable a bunch of segments to no avail), but I did ask a friend for his perception (who I know also uses my async fork) and he confirms that the startup feels slower.
To clarify, by startup I mean the period of time between when I launch a new terminal instance and when the prompt is rendered so I can start typing my commands.
So maybe to start the discussion with something, have you heard a similar feedback before? Do you have any idea what might be the cause? Have you specifically attempted to optimize the startup time, or it hasnāt been your focus so far?
Iām happy to assist with whatever I can, running experiments, performing benchmarks (how?), etc. At this point I dont have a powerlevel configuration I like (so we can start with some default and use it as an example).
Iām on Arch Linux using kitty terminal, zsh 5.7.1.
To me personally itās very important to get startup time to a minimum, I launch new terminal windows all the time and it feels annoying when I can notice the āloadingā. This is a lot more annoying than watching slow sections load (as long as they are asynchronous and not blocking my typing), so if I had to choose, Iād rather have slower async sections but faster startup.
š
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 79 (59 by maintainers)
Guys, check it out: https://gist.github.com/romkatv/8b318a610dc302bdbe1487bb1847ad99. Instant prompt! š
Itās a bit gimmicky but it does reduce the perceived ZSH startup latency a lot. Youāll need to define a āloadingā prompt that matches your real prompt to achieve best results. For example, Iām using the stock āleanā two-line prompt, so I have this as my loading prompt:
For @maximbaz this should work, I think:
Check out the gist. It has instructions at the top. To make it more interesting, add
sleep 1at the bottom of your~/.zshrc. Let me know what you think.Frankly, me too š
Great š
I looked at your dotfiles and wrote it by hand.
Iāve an idea that might speed up startup quite a bit without too many code changes. Iāll give it a shot some time next week. Will report here whether it works or not.
Iāve made p10k startup about 2.5-3 times faster. Itās still not super fast but certainly better than before. Please give it a try and let me know if you see an improvement and whether startup latency is good enough now.
Here are some benchmarks. All runs are from my desktop running Ubuntu. Current directory is powerlevel10k Git repo. 100 runs per benchmarks. Reported numbers are for a single run.
Baseline: 5.01ms.
Powerlevel9k with default settings: 171ms
Powerlevel10k with default settings: 59.7ms
With these settings p10k looks the same as p9k.
Powerlevel10k with
~/.p10k.zsh: 78.6ms~/.p10k.zshwas generated byp10k configure. The choices donāt seem to have much of an effect on startup performance. The reported number is from what I suppose is the slowest configuration with the maximum number of bells and whistles. Hereās the configās header:I believe the last benchmark is the most important. For comparison, the same benchmark before my optimizations reports 231ms startup latency. Now itās 2.9 times faster.
Hahaha this is amazing! š Iām definitely keeping this!
BTW: it turns out my terminal doesnāt support
$+terminfo[u7]so while I can report this issue, I commented out the whole ācursor position checkā block and it works well for me, can you please clarify what is it for? Is it to catch when you switch to root session withsudo -s? I guess I could replace that commented block with simply(( EUID )) || return 0ā¦I donāt get credit for finding this issue. It was reported by users whose zsh broke.
Such commands need to run before instant prompt. They cannot be run between the instant and the real prompts because theyāll eat buffered keybard input (things like
ls ~/projectsthat got typed when instant prompt was showing). This isnāt important though. What is important is that restructuring zshrc is too difficult for most users to and I cannot automate it. Moving interactive commands intospecial_hook(), or moving them above instant prompt ā are both too hard.@sinetoami I encourage you to post your findings as you go. I might be able to guess the culprit before you find the smallest possible test case.
Correct. If you make your window scroll while zsh is still loading, the āloadingā prompt wonāt be properly erased.
Ideally, it should be
prompt-height + nwherenis configurable. Iāll do it this way in p10k.This is intentional. Itās the best way I found to avoid the problems I mentioned earlier. I figured this is better than calling
clearbecause it gives users freedom. Anyone who liked the previous behavior can simply callclearon their own before callinginstant-zsh-pre.Iām gonna try to integrate instant-zsh into p10k. Not sure how hard it is but worth a try.
I still cannot believe my eyes how awesomely fast this is š
The current implementation works for me out of the box š
Just out of curiosity, how did you find the argument to
instant-zsh-prefor me (which is perfect btw), did you compose it by hand or there is a way to get this string out of the rendered prompt?@sinetoami Glad to hear youāve made your zsh load faster š Thanks for feedback, keep it coming.
P.S.
The āleanā style that you can choose in
p10k configureis really much better thanp10-pure.zsh. The latter is an exact replication of Pure, which isnāt that good.Iāve watched your screencast a few more times and I think I understand whatās going on there. I see that your zsh isnāt very fast to load but I cannot say whether there is difference in latency between zinc and p10k.
Is it possible that you perceive difference in latency because zinc is printing an empty line when it starts up? Maybe you can tell it not to print it? Or, alternatively, you can print the empty line when using p10k. I donāt know at which point zinc prints the empty line so you might want to try several things in order to replicate the same delays.
~/.zshrc.Add
echosomewhere in~/.zshrc. Perhaps before p10kzplugin ice.Add
echoto p10kzplugin ice.Add
print-line() { echo; add-zsh-hook -D precmd print-line }; add-zsh-hook precmd print-lineto the p10kzplugin ice.Iāve attempted to check whether zplugin might be making things slower than they should be. The short answer is no. When powerlevel10k is the only loaded plugin, sourcing it directly is 11ms faster than loading it with zplugin. Itās expected to be faster because it must take some time to load zplugin itself. The extra 11ms added by zplugin isnāt much, and it might pay off if zplugin reduces the total loading time when using many plugins (I havenāt tried to verify this).
Iāve recorded a screencast showing what Iāve measured and how:
The screencast starts with the following docker command:
It installs zsh and zplugin on Debian and logs in as a user with the following
~/.zshrc:Note that powerlevel10k and its config are loaded with zplugin.
After logging in, the current directory is changed to
~/.zplugin/plugins/romkatv---powerlevel10kbecause itās more interesting to observe what happens next if you are in a Git repository. You can see thattrueis instant whileexec zshis almost instant.The following command is used to measure zsh startup latency:
It repeatedly starts interacive zsh sessions and exits them once the first prompt renders. The command takes 5.115s (51ms per run).
Then
~/.zshrcis edited so that powerlevel10k and its config are sourced directly, without zplugin. Hereās the new~/.zshrc.After starting a new zsh session everything proceeds as before. This time the benchmark completes in 4.016s (40ms per run).
Thanks to docker, it should be relatively straightforward to reproduce this screencast for everyone who wishes to do so.
@sinetoami Your benchmark results indicate that p10k loads slightly faster than zinc.
Now, since the results of this benchmark donāt match your experience when using zsh with your real zsh config files, it means there is something in them that makes it different from the benchmark. Something that causes p10k load slower than it does in the benchmark. You can try to figure out what it is by removing parts of your config and checking when loading time improves. The first thing I would suggest is to load p10k without zplugin. Simply clone powerlevel10k repository and put
source ~/.p10k-pure.zshandsource ~/powerlevel10k/powerlevel10k.zsh-themein your~/.zshrc.Iāve fixed bugs in my previous implementation and rolled it forward. I had to disable some optimizations for zsh < 5.4 due to bugs in quoting that I donāt want to write workarounds for. I implemented a few extra optimizations.
Now p10k loads in 37 ms on my machine (6x improvement). Not instant but decently fast. This time includes starting zsh, sourcing
~/p10k.zsh, loading the theme and rendering the first prompt. Note that the first prompt is complete, unlike with some other themes that will give you just the current directory and then repaint prompt asynchronously when extra data becomes available.I think itās possible to shave off another 10 ms or so but more than that will be difficult. Unless someone complains loudly enough, Iāll leave the code be.
I also might have to revert the change if I broke something again. The changes are quite complex, so there is non-trivial risk of breakage.
I would appreciate if someone on this issue could update powerlevel10k and verify that loading has gotten faster.
FYI: Iāve reverted my optimizations as they were causing some issues and I donāt have the time to debug them right now. Will debug and roll forward later this week.
I was thinking the same thing.
Itās certainly possible. One non-trivial aspect is handling different combinations of permissions and file/directory ownership. Not too difficult. The thing that is stopping me from implementing this right now is potential interaction with plugin managers.
Iāll wait for the fallout from my recent optimizations to subside and then add zcompile once bug reports stop pouring in.
I donāt think there is an unavoidable trade off between these goals. Maybe sometimes you have to choose one over the other but in many cases you can have both. Powerlevel10k is slow to start and fast to use simply because I optimized for the latter without caring for the former. Things you donāt care about tend to be slow but it doesnāt mean they cannot be made fast.