Me and Claude went on a dotfiles journey the other day...
The Flex πͺ
π time zsh -i -c exit
zsh -i -c exit 0.02s user 0.01s system 87% cpu 0.033 total
33 milliseconds. That's faster than most people can blink. While others wait half a second
for their shell to load, we're already productive.
The Challenge
Most zsh configurations suffer from slow startup times ranging from 200ms to 500ms or more. Heavy frameworks like Oh-My-Zsh can push startup times beyond 1 second. Our goal was to achieve blazingly
fast shell initialization while maintaining full functionality for a modern development environment.
The Result
Final startup time: 33ms - putting us in the top 0.1% of shell performance.
Core Optimization Strategy
1. KISS Philosophy: Single-File Architecture
Instead of fragmenting configuration across multiple files, we organized everything within .zshrc
using clear section headers:
### BREW
### FZF
### COMPLETIONS
### NVM
### DOCKER
### KUBE
### PYTHON
### RUBY
This eliminates the overhead of sourcing multiple files while keeping code organized and maintainable.
2. Aggressive Lazy Loading
The biggest performance wins came from deferring expensive operations until actually needed:
NVM (Node Version Manager)
load_nvm() {
unset -f npm npx yarn nvm load_nvm 2>/dev/null || true
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \."$NVM_DIR/bash_completion"
}
npm() { load_nvm; npm "$@"; }
npx() { load_nvm; npx "$@"; }
yarn() { load_nvm; yarn "$@"; }
nvm() { load_nvm; nvm "$@"; }
Python Environment (pyenv)
function load_pyenv() {
if command -v pyenv &> /dev/null; then
eval "$(pyenv init --path)"
eval "$(pyenv init - --no-rehash)"
if which pyenv-virtualenv-init > /dev/null; then
eval "$(pyenv virtualenv-init -)"
fi
pyenv virtualenvwrapper
unset -f load_pyenv
fi
}
alias pyenv='load_pyenv && pyenv'
The Fuck (command correction)
function init_thefuck() {
unalias fuck
unset -f init_thefuck
eval $(thefuck --alias)
fuck
}
alias fuck="init_thefuck"
3. Strategic Performance Settings
Completion Optimization
# Fast completion initialization
compinit -C # Skip security checks for speed
# Completion caching
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache
zstyle ':completion:*' accept-exact '*(N)'
Disable Expensive Features
# Turn off features that slow startup
unsetopt AUTO_CD
unsetopt AUTO_PUSHD
unsetopt PUSHD_IGNORE_DUPS
unsetopt FLOW_CONTROL
4. Smart Git Branch Caching
Instead of running git
commands on every prompt render, we cache branch information:
function git_ps1 {
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
return
fi
# Use cached branch info
if [[ -n $GIT_BRANCH_CACHE ]]; then
echo -n "($GIT_BRANCH_CACHE)"
else
local branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ -n $branch && $branch != "HEAD" ]]; then
export GIT_BRANCH_CACHE="$branch"
echo -n "($branch)"
fi
fi
}
# Clear cache when changing directories
function git_branch_cache_clear() {
unset GIT_BRANCH_CACHE
}
add-zsh-hook chpwd git_branch_cache_clear
5. Conditional Loading
Only load completions and tools that are actually installed:
### KUBE
if command -v kubectl &> /dev/null; then
source <(kubectl completion zsh)
fi
### DOCKER
if command -v docker &> /dev/null; then
fpath=("$HOME/.docker/completions" $fpath)
fi
6. Smart Hooks
Use hooks sparingly and efficiently:
# Auto-load NVM when entering projects with .nvmrc
maybe_nvm_after_cd() {
local dir
dir=$(pwd)
while [ "$dir" != "/" ]; do
if [ -f "$dir/.nvmrc" ]; then
load_nvm
nvm use 2>/dev/null || true
return
fi
dir=$(dirname "$dir")
done
}
add-zsh-hook chpwd maybe_nvm_after_cd
Key Principles Applied
- Lazy Everything: Defer expensive operations until needed
- Cache Aggressively: Store computation results and reuse them
- Conditional Loading: Only load what's installed and needed
- Single File: Avoid sourcing overhead by keeping everything in one organized file
-
Profile and Measure: Use
time zsh -i -c exit
to validate improvements
What We Avoided
- Oh-My-Zsh: Adds 200-400ms overhead
-
Multiple sourced files: Each
source
adds ~5-10ms - Synchronous tool initialization: NVM, pyenv, etc. add 50-200ms each
- Complex prompt calculations: Git status checks on every render
- Unnecessary zsh options: Many defaults are performance killers
The Outcome
With these optimizations, we achieved:
- 33ms startup time (top 0.1% performance)
- Full development environment (Node, Python, Docker, Kubernetes)
- Rich completions for all tools
- Maintainable single-file configuration
- Zero functionality compromised
The key insight: aggressive lazy loading combined with smart caching and conditional execution can
deliver both speed and functionality without compromise.
Top comments (0)