🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

我的終端運作速度很慢。每次打開新分頁,都要等一會兒才能開始輸入,非常煩人。我決定深入研究一下,在 Claude Code 的幫助下,啟動時間從 770 毫秒縮短到了 40 毫秒,提升了 19 倍。

問題

倒不是我囤積太多工具了。我的 .zshrc 檔案裡大部分東西都是我需要的,但每多加一個都會增加 shell 的啟動時間。老實說,我之前沒研究過這個問題,就一直湊合著用。後來,John Lindquist 前幾天發了個帖子,我就想,不如讓 Claude Code 幫我加速一下。

{%embed https://x.com/johnlindquist/status/1993037322984866168 %}

測量基線

我首先需要知道情況有多糟:

for i in 1 2 3 4 5; do /usr/bin/time zsh -i -c exit 2>&1; done

哎呀:

0.94 real
0.71 real
0.74 real
0.73 real
0.72 real

平均每次啟動 shell 耗時約 770 毫秒。光是打開一個終端就幾乎要花一秒鐘。這可不好。

是什麼拖慢了進度

克勞德·科德幫我找到了主要罪魁禍首:

| 工具 | 影響 | 為什麼它很糟糕 |

|------|--------|--------------|

| nvm | 耗時約 300-500 毫秒 | 每次都會載入整個 Node.js 環境 |

| pyenv 初始化 | 耗時約 100-200 毫秒 | Python 版本管理初始化 |

| 安全性指令 | 約 50-100 毫秒 | 從 macOS 鑰匙圈取得 API 金鑰 |

| brew shellenv | ~30-50毫秒 | 執行子shell以取得Homebrew路徑 |

| gcloud 程式碼補全 | 約 20-30 毫秒 | Google Cloud 程式碼補全 |

重大突破:懶加載

大多數工具都不需要提前加載,直到我實際使用它們時才加載。所以,把那些耗時耗力的軟體等到第一次執行指令時再載入。

自毀包裝紙救場

這是巧妙之處。感謝 Claude Code。這些包裝函數在首次使用後會自動移除:

  1. 首次呼叫:包裝器執行,執行緩慢的初始化過程,然後刪除自身。

  2. 之後:直接執行,零開銷

每次療程只需支付一次費用。

不用了,懶加載

而不是這段啟動緩慢的程式碼:

# Before: runs every shell startup (~400ms)
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
nvm use default --silent

現在,我使用包裝函數:

# After: only runs when you actually need node/npm/npx
nvm() {
  unset -f nvm node npm npx
  [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
  [ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"
  nvm "$@"
}
node() { nvm use default --silent; unfunction node npm npx; node "$@"; }
npm() { nvm use default --silent; unfunction node npm npx; npm "$@"; }
npx() { nvm use default --silent; unfunction node npm npx; npx "$@"; }

2025年11月28日更新:我已放棄使用nvm ,改用fnm ,因此也移除了nvmnodenpmnpx封裝函數。如果您確實需要使用nvm ,請保留這些封裝函數。

unset -funfunction指令會在首次使用後移除包裝器。之後,工具就像正常載入過一樣。

pyenv 也受到了同樣的對待。

# Before
eval "$(pyenv init -)"

# After
pyenv() {
  unset -f pyenv
  eval "$(command pyenv init -)"
  pyenv "$@"
}

第一次呼叫pyenv需要大約 150 毫秒進行初始化,之後就會一直直接執行。

Google Cloud SDK

gcloud() {
  unset -f gcloud gsutil bq
  [ -f "$HOME/.local/google-cloud-sdk/path.zsh.inc" ] && . "$HOME/.local/google-cloud-sdk/path.zsh.inc"
  [ -f "$HOME/.local/google-cloud-sdk/completion.zsh.inc" ] && . "$HOME/.local/google-cloud-sdk/completion.zsh.inc"
  gcloud "$@"
}
gsutil() { gcloud; gsutil "$@"; }
bq() { gcloud; bq "$@"; }

自製緩存

Homebrew 的環境不會經常變化,所以只需快取即可:

# Before: subshell every time
eval "$(/opt/homebrew/bin/brew shellenv)"

# After: cache to file, only regenerate if brew changes
if [[ ! -f ~/.zsh_brew_cache || ~/.zsh_brew_cache -ot /opt/homebrew/bin/brew ]]; then
  /opt/homebrew/bin/brew shellenv > ~/.zsh_brew_cache
fi
source ~/.zsh_brew_cache

API金鑰懶惰

每次啟動 shell 時,我都會存取 macOS 鑰匙圈:

# Before: slow keychain lookup every time
export OPENAI_API_KEY=$(security find-generic-password -a $USER -s openai_api_key -w)

由於我只需要它用於 npm 相關操作,所以我把它移到了 npm 包裝器中:

npm() {
  nvm use default --silent
  unfunction node npm npx
  [ -z "$OPENAI_API_KEY" ] && \
    export OPENAI_API_KEY=$(security find-generic-password -a $USER -s openai_api_key -w)
  npm "$@"
}

2025年11月28日更新:如上所述,我已切換到fnm ,因此我修改了程式碼,因為我移除了npm封裝函數。現在,對於我的OpenAI API金鑰,我只需在需要時呼叫一個函數即可:

# === Lazy-load OPENAI_API_KEY ===
openai_key() {
  export OPENAI_API_KEY=$(security find-generic-password -a $USER -s openai_api_key -w)
}

我的簡報中將詳細介紹 macOS 鑰匙圈的使用技巧

其他快速致勝之道

我還清理了一些基本的東西:

  • 將 7 種不同的 PATH 修改合併成一行

  • 刪除重複的GPG_TTY匯出

  • 修復了順序問題,現在STARSHIP_CONFIG會在starship init之前設定。

結果

經歷所有變化之後:

for i in 1 2 3 4 5; do /usr/bin/time zsh -i -c exit 2>&1; done
0.06 real
0.04 real
0.04 real
0.03 real
0.04 real

平均值:約 40 毫秒

| 改善前 | 改善後 | 提升後 |

|--------|-------|-------------|

| 770毫秒 | 40毫秒 |速度提升95% |

所謂的“權衡”,其實並非如此

是的,每種工具首次使用時都需要一次付費:

  • 第一個node / npm / npx :+400毫秒

  • 首次pyenv :+150毫秒

  • 首次gcloud :+50毫秒

但這只會在每個終端會話中發生一次,而且與命令實際執行的操作相比,這幾乎難以察覺。

試試看

如果你的 shell 啟動速度很慢,先測量總啟動時間:

time zsh -i -c exit

如果超過 200 毫秒,表示還有提升空間。要查看具體是哪個環節出了問題,請分析你的 .zshrc 檔案或你正在使用的任何其他 shell:

# Add to top of .zshrc
zmodload zsh/zprof

# Add to bottom
zprof

這會詳細列出哪些特定命令佔用了您的啟動時間。

我更新後的 Shell 設定文件

這是我更新的 shell,其中包含了所有效能最佳化。

# === Early exports (no subshells) ===
export HOMEBREW_NO_AUTO_UPDATE=1
export GOPATH=$HOME/go
export PYENV_ROOT="$HOME/.pyenv"
export POMERIUM_CLI_USER_DATA_DIRECTORY=$HOME/.local/share/pomerium
export STARSHIP_CONFIG=~/.config/starship.toml
export GPG_TTY=$(tty)
export HISTORY_IGNORE="(g\src|g\sra|g\sa|g\srhh|ls|cd|cd ..|pwd|clear|exit|logout|history|alias|unalias|set|unset|env|whoami|date|uptime|tree|code|code \.|vim|nvim|nano|trash|security)( .*)?"
export PATH="$HOME/.bun/bin:$HOME/.antigravity/antigravity/bin:$HOME/.config/herd-lite/bin:$HOME/.codeium/windsurf/bin:$HOME/.console-ninja/.bin:/opt/homebrew/anaconda3/bin:$GOPATH/bin:$PYENV_ROOT/bin:$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"

openai_key() {
  export OPENAI_API_KEY=$(security find-generic-password -a $USER -s openai_api_key -w)
}

# === Cache brew shellenv ===
if [[ ! -f ~/.zsh_brew_cache || ~/.zsh_brew_cache -ot /opt/homebrew/bin/brew ]]; then
  /opt/homebrew/bin/brew shellenv > ~/.zsh_brew_cache
fi
source ~/.zsh_brew_cache

# === Zsh options ===
setopt autocd
autoload -U history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^[[A" history-beginning-search-backward-end
bindkey "^[[B" history-beginning-search-forward-end

# === Prompt ===
eval "$(starship init zsh)"

# === fnm ===
eval "$(fnm env --use-on-cd --shell zsh)"

# === Lazy-load pyenv ===
pyenv() {
  unset -f pyenv
  eval "$(command pyenv init -)"
  pyenv "$@"
}

# Lazy load Cargo - defers initialization until first use
cargo() {
  unset -f cargo rustc rustup
  source $HOME/.cargo/env
  cargo "$@"
}
rustc() {
  unset -f cargo rustc rustup
  source $HOME/.cargo/env
  rustc "$@"
}
rustup() {
  unset -f cargo rustc rustup
  source $HOME/.cargo/env
  rustup "$@"
}

# === Plugins ===
source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

# === Atuin ===
. "$HOME/.atuin/bin/env"
eval "$(atuin init zsh --disable-up-arrow)"

# === Lazy-load gcloud ===
gcloud() {
  unset -f gcloud gsutil bq
  [ -f "$HOME/.local/google-cloud-sdk/path.zsh.inc" ] && . "$HOME/.local/google-cloud-sdk/path.zsh.inc"
  [ -f "$HOME/.local/google-cloud-sdk/completion.zsh.inc" ] && . "$HOME/.local/google-cloud-sdk/completion.zsh.inc"
  gcloud "$@"
}
gsutil() { gcloud; gsutil "$@"; }
bq() { gcloud; bq "$@"; }

# === Aliases ===
alias flushdns='sudo dscacheutil -flushcache;sudo killall -HUP mDNSResponder'
alias zshconfig='less ~/.zshrc'
alias nr='npm run'
alias ni='npm i'
alias '$'=''
alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
alias dotfiles='/opt/homebrew/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
alias g='git'
alias code='code-insiders'
alias c='cursor -r'
alias p='pnpm'
alias pi='pnpm i'
alias dcu='docker compose up -d'
alias dcd='docker compose down'
alias mermaid='mmdc'
alias sniffly='uvx sniffly init'

# === Functions ===
# checkout a pull request in a git worktree
cpr() {
  pr="$1"
  remote="${2:-origin}"
  branch=$(gh pr view "$pr" --json headRefName -q .headRefName)
  git fetch "$remote" "$branch"
  git worktree add "../$branch" "$branch"
  cd "../$branch" || return
  echo "Switched to new worktree for PR #$pr: $branch"
}

rmmerged() {
  git branch --merged | grep -v "*" | grep -v \"master\" | xargs -n 1 git branch -d && git remote prune origin
}

nb() {
  branch="$1";
  git remote -v | grep -q [email protected]:pomerium/ && git checkout -b "nickytonline/$branch" || git checkout -b $branch;
}

db() {
  branch="$1";
  git remote -v | grep -q [email protected]:pomerium && git branch -D "nickytonline/$branch" || git branch -D $branch;
}

glog() {
  git log --oneline --decorate --graph --color | less -R
}

總結

開發工具的開銷會迅速累積,很容易被這些細小的缺陷所掩蓋。這種延遲載入模式可以解決這個問題,而且沒有任何真正的缺點。

非常感謝 John L. 和 Claude Code 幫助我找出瓶頸和解決方案。

注意:效能影響資料和對比表格是在 Claude Code 的幫助下產生的。實際里程可能因您的具體配置而異。 😅

如果你想和我保持聯繫,我的所有社交帳號都在nickyt.online

期待下次!

照片由Marc Sendra Martorell拍攝,來自Unsplash


原文出處:https://dev.to/nickytonline/how-i-used-claude-code-to-speed-up-my-shell-startup-by-95-m0f


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝15   💬3   ❤️3
315
🥈
我愛JS
📝1   💬3   ❤️2
45
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付