Zsh Shell 在初始启动期间花费了异常长的时间

Sac*_*hin 2 terminal zsh prompt zshrc oh-my-zsh

我目前正在使用 ubuntu 20 并使用 zsh + oh my zsh shell 。问题是 zsh shell 的启动时间异常长。从正确的角度来看,与使用 time 命令相比,它几乎比原始 bash 慢 9 倍。

使用原始 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
Run Code Online (Sandbox Code Playgroud)

时间检查使用 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
Run Code Online (Sandbox Code Playgroud)

我想再次清除 zsh 中的延迟仅在 start 时打开终端时发生,而不是在一般使用期间。我已禁用所有插件并使用 powerlevel10k 主题,尽管我可以肯定地说它与主题无关。在我更改为 zsh shell 后,我立即注意到了这种减速,在我安装了 oh my zsh 后甚至变得更糟我还告诉我的一些朋友做这个测试,他们的 zsh 时间比原始 bash 略高,这是可以接受的,但是我的似乎完全不正常。

也欢迎一般建议,但更具体地说,我想问一下,我是否可以实际检查终端在后台究竟做了什么,而在 zsh 中启动大约需要 3 秒,而在 bash 中启动需要 0.2 秒

如果有帮助,这是我的 .zshrc 文件

编辑 - 我尝试使用原始 zsh(没有哦我的 zsh)进行相同的测试结果很有趣,现在 zsh shell 的启动速度大约慢 4 倍,平均大约 1.2 秒,而 zsh+oh my zsh 为 3 秒

cat*_*net 5

您可以通过放置zmodload zsh/zprof在 zshrc 的顶部和zprof底部来检查哪些函数在 zsh 启动期间花费的时间最长。下次打开新会话时,您会得到很好的细分。

希望这可以帮助您深入了解加载时间较长的内容。

老实说 oh-my-zsh 有点笨拙,它没有优化函数的加载,只是获取所有内容 - 如果其中一个资源运行大量程序,则您的 shell 将不得不等到它执行,直到出现提示负载。

我手工编写了自己的 zsh 配置并使用 Zinit https://github.com/zdharma/zinit加载插件。我的外壳在几毫秒内启动。

  • 两个最慢的函数是handle_completion_insecurities 和anon。handle_completion_insecurities 来自 oh-my-zsh https://github.com/NobbZ/oh-my-zsh/commit/08d22c53e7ddffa1d1d696ad09279d67d5dd2388 它似乎阻止 compinit 抱怨不安全的文件。要关闭它 - ZSH_DISABLE_COMPFIX=true 对我来说,这只发生在 root 中。我的 zshrc 中有这个: `[[ $UID = 0 || -n $SUDO_USER ]] && compinit -u || compinit` 选项 -u 接受不安全的文件。匿名函数可以是任何东西。它们被写成 () { code } 并自动运行,无需调用。 (2认同)