Zsh Shell taking abnormally long time during initial startup
Asked Answered
F

3

5

I am currently using ubuntu 20 and using zsh + oh my zsh shell . The issue is zsh shell is taking abnormally long time to start up. To puts things in perspective , its almost 9 times slower than raw bash when compared using time command

Time Check using Raw bash

for i in $(seq 1 10); do /usr/bin/time bash -i -c exit; done
exit
0.02user 0.07system 0:00.19elapsed 45%CPU (0avgtext+0avgdata 1816maxresident)k
136inputs+0outputs (3major+1737minor)pagefaults 0swaps
exit
0.05user 0.04system 0:00.17elapsed 52%CPU (0avgtext+0avgdata 1820maxresident)k
0inputs+0outputs (0major+1737minor)pagefaults 0swaps
exit
0.02user 0.06system 0:00.18elapsed 42%CPU (0avgtext+0avgdata 1824maxresident)k
0inputs+0outputs (0major+1745minor)pagefaults 0swaps
exit
0.08user 0.03system 0:00.21elapsed 51%CPU (0avgtext+0avgdata 1828maxresident)k
0inputs+0outputs (0major+1743minor)pagefaults 0swaps
exit
0.00user 0.06system 0:00.14elapsed 40%CPU (0avgtext+0avgdata 1816maxresident)k
0inputs+0outputs (0major+1736minor)pagefaults 0swaps
exit
0.02user 0.05system 0:00.14elapsed 50%CPU (0avgtext+0avgdata 1820maxresident)k
0inputs+0outputs (0major+1738minor)pagefaults 0swaps
exit
0.00user 0.06system 0:00.13elapsed 46%CPU (0avgtext+0avgdata 1820maxresident)k
0inputs+0outputs (0major+1741minor)pagefaults 0swaps
exit
0.01user 0.05system 0:00.14elapsed 40%CPU (0avgtext+0avgdata 1816maxresident)k
0inputs+0outputs (0major+1738minor)pagefaults 0swaps
exit
0.00user 0.07system 0:00.14elapsed 48%CPU (0avgtext+0avgdata 1816maxresident)k
0inputs+0outputs (0major+1738minor)pagefaults 0swaps
exit
0.01user 0.06system 0:00.13elapsed 50%CPU (0avgtext+0avgdata 1816maxresident)k
0inputs+0outputs (0major+1737minor)pagefaults 0swaps

Time Check using zsh + oh my zsh

for i in $(seq 1 10); do /usr/bin/time zsh -i -c exit; done
0.67user 0.82system 0:02.54elapsed 58%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8337minor)pagefaults 0swaps
0.66user 1.01system 0:02.88elapsed 57%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8329minor)pagefaults 0swaps
0.51user 1.11system 0:03.17elapsed 50%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8345minor)pagefaults 0swaps
0.74user 0.76system 0:02.78elapsed 53%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8339minor)pagefaults 0swaps
0.59user 0.99system 0:02.74elapsed 57%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8326minor)pagefaults 0swaps
0.80user 0.86system 0:02.88elapsed 57%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8339minor)pagefaults 0swaps
0.63user 1.02system 0:02.78elapsed 59%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8330minor)pagefaults 0swaps
0.87user 0.89system 0:03.08elapsed 57%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8325minor)pagefaults 0swaps
0.68user 0.98system 0:02.89elapsed 57%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8323minor)pagefaults 0swaps
0.71user 0.88system 0:02.81elapsed 56%CPU (0avgtext+0avgdata 4676maxresident)k
0inputs+0outputs (0major+8338minor)pagefaults 0swaps

I would like to clear it again that delay in zsh only happens when opening terminal at start , not during general usage. I have disabled all plugins and using powerlevel10k theme , although i can definitely say it has nothing to do with theme. I noticed this slowdown immediately after i had changed to zsh shell which got even worsened after i installed oh my zsh I also told some of my friends to do this test and their zsh timings were very very slightly higher than raw bash , well thats acceptable but mine seems totally abnormal.

General recommendations are also welcome but more specifically i would like to ask if there's anyway i can actually check what exactly does the terminal does in background while its taking approx 3 seconds to start up in zsh as opposed to 0.2 seconds on bash

Here's my .zshrc file if that helps

Edit - I tried doing same test with Raw zsh ( without oh my zsh ) The results are interesting , now the zsh shell is approx 4 times slower to start , it averages around 1.2 seconds as opposed to 3 seconds seconds with zsh+oh my zsh

Freakish answered 21/6, 2020 at 13:32 Comment(2)
What about without using oh-my-zsh?Zygophyllaceous
@Zygophyllaceous good suggestion , here's the results with raw zsh ( without oh my zsh ) - del.dog/raw/zoocolowunFreakish
L
22

You can check what functions are taking the longest during zsh startup by placing zmodload zsh/zprof at the top of your zshrc and zprof at the bottom. You will get nice breakdown next time you open new session.

Hopefully this might help you drill down into what is taking long to load.

To be honest oh-my-zsh is a bit of a hog and does not optimize loading of functions and just sources everything - If one of those sources runs a hog of a program, your shell will have to wait until it executes until the prompt loads.

I hand coded my own zsh config and use Zinit https://github.com/zdharma/zinit to load plugins. My shell launches in milliseconds.

Looselimbed answered 22/6, 2020 at 10:59 Comment(3)
Thanks man for that method to check what functions are being run during startup , i will definitely check out your gitFreakish
Although it can't understand any of it , do you notice anything abnormal here - del.dog/cytahuving.txtFreakish
The two slowest functions are handle_completion_insecurities and anon. handle_completion_insecurities is from oh-my-zsh github.com/NobbZ/oh-my-zsh/commit/… It seems to stop compinit from complaining about insecure files. To turn it off - ZSH_DISABLE_COMPFIX=true For me this only happens in root. I have this in my zshrc: [[ $UID = 0 || -n $SUDO_USER ]] && compinit -u || compinit Option -u accepts insecure files. Anon functions could be anything. They are written as () { code } and run automatically without invocation.Looselimbed
P
5

If what you care about is getting a usable shell quickly when you start Zsh, here's what you can do:

  1. Type p10k configure. This command comes from Powerlevel10k, which you are already using.
  2. When get asked by the wizard whether to enable Instant Prompt, choose either Quiet or Verbose but not Off.

Now for all practical purposes Zsh will start instantly. You can enable as many plugins as you like and it'll still be instant. You can find details here and here.

Note that you'll still get the same result from time /usr/bin/time zsh -i -c exit. This benchmark doesn't measure Zsh startup time. It gives neither the lower nor the upper bound for Zsh startup time. Its results can be arbitrarily higher or lower than the real Zsh startup time.

Paginal answered 22/6, 2020 at 5:36 Comment(5)
Thanks for replying , Firstly the .p10k.zsh file i am using isn't directly generated by p10k configure , i have got that file from a friend who has changed the looks a bit according to our preference - here's my current p10k configure file - del.dog/aphusyqigr.go , As far as the accuracy of the time command is concerned , i find it fairly accurate because i even tested terminal startup time on zsh+ohmyzsh using a stopwatch the best i can , and it always seemed to almost touch the 3 second mark like the time command indicatesFreakish
If you don't want to run p10k configure, you can enable instant prompt by manually adding a few lines at the top of your ~/.zshrc. See docs. As for the usefulness of time zsh -ic exit, it can be easily demonstrated that you by changing your zshrc you can make this command report arbitrary large or arbitrary small numbers. Optimizing for the results of this command is a very bad idea.Paginal
thanks that definitely improved the initial load time , refering to the answer below i got to know about zsh profiling , i have found the functions taking longest timeFreakish
i have gained some advantage from your theme's instant prompt , although i would try to improve it even further by trying the reduce the time consumed by those functionsFreakish
You are about to spend a lot of time for nothing. Reducing the time taken by any function from the profile you've taken will not have any effect on Zsh startup time. Try the following. First, enable instant prompt as I describe above. Type zsh. If prompt doesn't appear instantly, file a bug against powerlevel10k. Now add foo() { sleep 1 }; foo at the bottom of zshrc. Type zsh. It still starts instantly, yet your benchmarks and profiles show that foo takes a lot of time.Paginal
D
5

It was taking around 5 to 6 seconds to load zsh/ new terminal window for me. you can use /usr/bin/time zsh -i -c exit command to exactly calculate the time it takes. I followed these steps to fix it

  • I added zmodload zsh/zprof to start and zprof to end of my ~/.zshrc file.
  • Then I ran exec zsh to reload zsh session. Do not use source ~/.zshrc command to reload since it can cause problems as stated in the docs
  • It gave me the time break down of all the things while loading zsh
  • It turned out is_update_available was taking 95% of load time.
  • I disabled auto-update by DISABLE_AUTO_UPDATE="true" in my .zshrc file.
  • Then ran exec zsh and my problem was solved
Debbee answered 17/6, 2022 at 13:0 Comment(1)
the auto_update tip actually worked, it took 1-2secs off my startup time.Metz

© 2022 - 2024 — McMap. All rights reserved.