perf(zsh): defer proto activation to speed up shell startup#31
perf(zsh): defer proto activation to speed up shell startup#31
Conversation
Proto activation's subprocess evaluation takes ~17ms, delaying shell interactivity. Move proto.zsh loading to zsh-defer so it loads after the shell is interactive rather than during startup. This reduces shell startup time by 17.6ms (62.9ms → 45.3ms, -28%). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request optimizes shell startup performance by deferring the sourcing of proto.zsh using zsh-defer. The review feedback points out that deferring the entire file may prevent environment variables from being available to subsequent scripts and recommends adding a fallback check for the zsh-defer function to avoid potential command-not-found errors.
| # proto activation is slow (~15ms subprocess); defer until after shell is interactive | ||
| zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh" |
There was a problem hiding this comment.
proto.zsh 内で PROTO_AUTO_INSTALL などの環境変数がエクスポートされていますが、ファイル全体を zsh-defer で遅延させると、その後に読み込まれる functions/ 以下のスクリプトや、シェル起動直後の操作でこれらの設定が反映されない期間が生じます。特に環境変数はツールの挙動に影響するため、同期的に設定することが望ましいです。
また、zsh-defer がロードされなかった場合に備えて、関数の存在チェックとフォールバックを追加することで、command not found エラーを防ぐことができます。
# proto activation is slow (~15ms subprocess); defer until after shell is interactive
export PROTO_AUTO_INSTALL=true
if (( $+functions[zsh-defer] )); then
zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh"
else
source "${ZSH_CONFIG_DIR}/tools/proto.zsh"
fi
PROTO_AUTO_INSTALL was deferred along with proto.zsh, creating a window where the variable was unset. Moving it to env.zsh ensures it is always available from shell startup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR reduces Zsh startup latency by deferring proto activate zsh --no-shim (which spawns a subprocess) until just before the first prompt, using zsh-defer loaded via Sheldon.
Changes:
- Stop eagerly sourcing
tools/proto.zshduring.zshrcstartup; instead defer it viazsh-deferaftersheldon source. - Move
PROTO_AUTO_INSTALL=trueexport fromtools/proto.zshintocore/env.zshso it’s set early and independent of deferred activation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| home/dot_zshrc | Defers proto activation with zsh-defer after Sheldon loads plugins. |
| home/dot_zsh.d/tools/proto.zsh | Removes PROTO_AUTO_INSTALL export; leaves only proto activate eval. |
| home/dot_zsh.d/core/env.zsh | Exports PROTO_AUTO_INSTALL=true as part of core environment setup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| eval "$(sheldon source)" | ||
|
|
||
| # proto activation is slow (~15ms subprocess); defer until after shell is interactive | ||
| zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh" |
There was a problem hiding this comment.
zsh-defer is called unconditionally. If sheldon source fails (or zsh-defer isn’t loaded for some reason), this will produce a command not found error and skip proto activation. Also, zsh-defer runs via prompt hooks; in interactive zsh -i -c '…' sessions (or other cases where the prompt isn’t shown), the deferred activation may never fire. Consider guarding and falling back to immediate source (e.g., when zsh-defer isn’t defined or when $ZSH_EXECUTION_STRING is set).
| zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh" | |
| # Fall back to immediate loading if zsh-defer is unavailable or if we're running | |
| # an interactive command string (for example: zsh -i -c '...'), where prompt-hook | |
| # based deferral may never fire. | |
| if [[ -n "${ZSH_EXECUTION_STRING:-}" ]] || ! (( $+functions[zsh-defer] )); then | |
| source "${ZSH_CONFIG_DIR}/tools/proto.zsh" | |
| else | |
| zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh" | |
| fi |
Summary
proto activate zsh --no-shimは毎回サブプロセスを起動するため、同期実行すると起動時に約 17ms かかる。sheldon sourceで読み込まれるzsh-deferを使い、シェルがインタラクティブになった直後に遅延実行することで起動時間を短縮した。ベンチマーク(hyperfine, 10 runs)
17.6ms 短縮(28% 改善)
機能への影響
zsh-deferはプロンプト表示の直前に発火するため、通常のインタラクティブ使用では体感上の差異はない。path.zshで$PROTO_HOME/binは既に PATH に含まれているため、遅延中も proto 管理ツールは参照可能。