ترمینال کند، عذاب روزانه
خلاصهٔ کاملتر
نویسنده میگه عملاً همهٔ کارش تو ترمینال اتفاق میافته — git، kubectl، tmux، ssh — و ابزاری که اینقدر زیاد ازش استفاده میکنه باید سریع باشه. هر لگ تو باز کردن تب جدید یا تایپ یه کاراکتر، چیزیه که روزی صدها بار حسش میکنه؛ به قول خودش «مرگ با هزار زخم». شل خودش تو حدود ۳۰ میلیثانیه بالا میاد، اونم با یه شل تعاملیِ کامل که completion و syntax highlighting و autosuggestion و fzf و direnv داره.
به گفتهٔ نویسنده، بزرگترین برد همون چیزیه که نیست: نه oh-my-zsh، نه prezto، نه هیچ plugin manager. میگه آدمها oh-my-zsh رو با صدها پلاگین نصب میکنن، شاید ۵٪ـش رو استفاده میکنن و بابت ۹۵٪ بقیه هر بار که شل باز میکنن با وقت و منابعشون هزینه میدن. خودش فقط سه تا پلاگین داره که یه بار با git کلون میشن و مستقیم تو .zshrc با source صدا زده میشن — بدون plugin manager که موقع استارت dependency حل کنه.
یه گلوگاه دیگه compinitـه که به طور پیشفرض هر بار همهٔ فایلهای completion رو از نظر امنیتی ممیزی میکنه. راهحل اینه که فقط اگه کش (.zcompdump) بیشتر از ۲۴ ساعت قدیمی باشه ممیزی کامل بشه، وگرنه با فلگ -C این بررسی رد بشه. یعنی یه بار compinit کامل در روز و بقیهٔ دفعات خوندن از کش.
برای ابزارهای سنگین، نویسنده از الگوی lazy-load استفاده میکنه. میگه nvm بدنامترین قاتل استارت شله و source کردن مستقیمش راحت میتونه نیم ثانیه اضافه کنه. به جاش یه تابع مینویسه که خودش رو موقع اولین استفاده جایگزین میکنه:
nvm() {
unset -f nvm
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh" --no-use
nvm "$@"
}اولین صدا زدن nvm، اون stub رو پاک میکنه، nvm واقعی رو source میکنه (با --no-use که حتی نسخهٔ node رو هم resolve نکنه) و آرگومانها رو فوروارد میکنه. همین الگو برای completionهای kubectl هم کار میکنه. نویسنده میگه هر چیزی که بهت میگه eval "$(tool init zsh)" رو تو .zshrc بذاری، کاندیدای lazy-loadـه؛ ولی direnv و fzf رو eager نگه میداره چون سریعان و مدام ازشون استفاده میکنه.
بخش دیگه پرامپت غیرمسدودکنندهست. یه پرامپتی که git status رو همزمان (synchronous) اجرا کنه، تو هر ریپوی بزرگی لگ میندازه و این لگ رو رو هر بار زدن Enter حس میکنی. نویسنده از pure استفاده میکنه که پرامپت رو فوری رندر میکنه و اطلاعات git رو به صورت async وقتی آماده شد پر میکنه. خود ترمینال هم مهمه: نویسنده Ghostty رو که GPU-accelerated و nativeـه با یه کانفیگ هفتخطی بهکار میبره.
برای اندازهگیری، نویسنده پیشنهاد میده با time zsh -i -c exit یا hyperfine زمان استارت رو بسنجی، و با profiler خود zsh (یعنی zmodload zsh/zprof بالای فایل و zprof تهش) ببینی وقت کجا میره. میگه زیر ۱۰۰ میلیثانیه خوبه و زیر ۵۰ عالیه؛ اگه ۵۰۰ یا بیشتر میبینی، کار داری. جمعبندیش اینه که بیشتر این بهینهسازیها دربارهٔ بیرون گذاشتن چیزهاست و باید سختگیر باشی که فقط چیزی رو اضافه کنی که واقعاً زیاد ازش استفاده میکنی.
نکات کلیدی:
- بزرگترین برد، حذف فریمورکهاست: نه oh-my-zsh، نه plugin manager؛ فقط چند پلاگین که مستقیم source میشن
- کش کردن compinit با فلگ -C تا روزی فقط یه بار ممیزی کامل اجرا بشه
- lazy-load کردن ابزارهای سنگین مثل nvm و kubectl با تابعی که خودش رو جایگزین میکنه
- پرامپت غیرمسدودکننده (مثل pure) که git status رو async پر میکنه
- اندازهگیری با time، hyperfine و zprof؛ زیر ۵۰ میلیثانیه استارت عالیه




