Skip to content

perf(zsh): defer proto activation to speed up shell startup#31

Draft
nyatinte wants to merge 2 commits intomainfrom
perf/zsh-startup-optimization
Draft

perf(zsh): defer proto activation to speed up shell startup#31
nyatinte wants to merge 2 commits intomainfrom
perf/zsh-startup-optimization

Conversation

@nyatinte
Copy link
Copy Markdown
Owner

@nyatinte nyatinte commented Apr 7, 2026

Summary

proto activate zsh --no-shim は毎回サブプロセスを起動するため、同期実行すると起動時に約 17ms かかる。sheldon source で読み込まれる zsh-defer を使い、シェルがインタラクティブになった直後に遅延実行することで起動時間を短縮した。

ベンチマーク(hyperfine, 10 runs)

平均 min max
main 62.9 ms ±4.0 ms 57.3 ms 68.7 ms
PR 45.3 ms ±3.0 ms 42.3 ms 51.5 ms

17.6ms 短縮(28% 改善)

機能への影響

zsh-defer はプロンプト表示の直前に発火するため、通常のインタラクティブ使用では体感上の差異はない。path.zsh$PROTO_HOME/bin は既に PATH に含まれているため、遅延中も proto 管理ツールは参照可能。

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>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread home/dot_zshrc
Comment on lines +22 to +23
# proto activation is slow (~15ms subprocess); defer until after shell is interactive
zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.zsh during .zshrc startup; instead defer it via zsh-defer after sheldon source.
  • Move PROTO_AUTO_INSTALL=true export from tools/proto.zsh into core/env.zsh so 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.

Comment thread home/dot_zshrc
eval "$(sheldon source)"

# proto activation is slow (~15ms subprocess); defer until after shell is interactive
zsh-defer source "${ZSH_CONFIG_DIR}/tools/proto.zsh"
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
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

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants