诊断命令
# 测试 interactive shell 启动时间
time zsh -i -c exit
# 测试 login shell 启动时间(会额外加载 ~/.zprofile)
time zsh -l -i -c exit
# 检查当前是否为 login shell
echo $0 # 输出 -zsh = login shell,zsh = 非 login shell逐文件计时
for f in ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin; do
if [ -f "$f" ]; then
start=$(python3 -c "import time; print(time.time())")
zsh -c "source $f" 2>/dev/null
end=$(python3 -c "import time; print(time.time())")
echo "$f: $(python3 -c "print(f'{($end-$start)*1000:.0f}ms')")"
fi
done常见瓶颈
| 来源 | 典型耗时 | 说明 |
|---|---|---|
| oh-my-zsh core | ~200ms | 基础框架开销 |
| spaceship theme | ~120ms | 功能丰富但慢 |
| zsh-syntax-highlighting | ~100ms | 每次初始化 |
| zsh-autosuggestions | ~60ms | 相对较小 |
| nvm 直接 source | ~200ms | 最常见的大坑 |
优化方案
1. 换轻量 prompt 框架(收益最大)
把 oh-my-zsh 整体换成 Starship,启动时间可降至 50-100ms:
brew install starship
# 在 .zshrc 末尾替换原有 theme 配置
eval "$(starship init zsh)"2. 保留 omz 但换轻量 theme
spaceship 换成 robbyrussell 可节省约 120ms。
3. nvm 懒加载
nvm 直接 source 约 200ms,改为懒加载只在首次调用时初始化:
export NVM_DIR="$HOME/.nvm"
_nvm_load() {
unset -f nvm node npm npx yarn pnpm
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && source "$NVM_DIR/bash_completion"
}
nvm() { _nvm_load; nvm "$@"; }
node() { _nvm_load; node "$@"; }
npm() { _nvm_load; npm "$@"; }
npx() { _nvm_load; npx "$@"; }4. compinit 缓存优化
每天只重建一次 dump,避免每次启动都全量扫描:
autoload -Uz compinit
if [ $(date +'%j') != $(stat -f '%Sm' -t '%j' ~/.zcompdump 2>/dev/null) ]; then
compinit
else
compinit -C
fi也可配合 ZSH_DISABLE_COMPFIX=true 跳过安全检查加速。
5. 关闭不必要的 oh-my-zsh 插件
只保留常用插件,每个插件都有启动开销:
# 重量级插件建议懒加载
plugins=(git) # 最小化配置参考时间基准
- 正常范围:< 200ms
- 可接受:200-500ms
- 需要优化:> 500ms
- 优化后目标:< 100ms(Starship 方案)