Почему zsh медленно запускается (и как это исправить)
Вы открываете новую вкладку терминала. Вы ждёте. Проходит одна секунда, затем две, может быть три. Наконец появляется приглашение zsh. Эта раздражающая задержка — не вина самой оболочки, почти всегда проблема в вашей конфигурации.
Чистая установка zsh запускается примерно за 50–100 миллисекунд. Когда время запуска раздувается до нескольких секунд, виновники предсказуемы: накладные расходы системы автодополнения, синхронная загрузка плагинов, тяжёлые темы и менеджеры версий языков вроде nvm или pyenv. Это руководство покажет вам, как определить, что именно работает медленно, и исправить это без полной переписи всей конфигурации.
Ключевые выводы
- Стандартный zsh запускается за 50–100 мс. Задержки в несколько секунд возникают из-за вашего
.zshrc, а не самой оболочки. - Используйте
zsh/zprofи/usr/bin/time zsh -i -c exit, чтобы точно определить узкие места перед внесением изменений. - Менеджеры версий языков (nvm, pyenv, conda) — самые частые виновники. Ленивая загрузка даёт немедленный результат.
- Вызывайте
compinitровно один раз, удалите неиспользуемые плагины и используйте лёгкую тему, чтобы дополнительно сократить время запуска.
Профилируйте перед оптимизацией
Догадки — пустая трата времени. В zsh встроен профайлер, который точно показывает, на что уходит время запуска.
Добавьте это в первую строку вашего ~/.zshrc:
zmodload zsh/zprof
Добавьте это в последнюю строку:
zprof
Откройте новый терминал. Вы увидите вывод примерно такого вида:
num calls time self name
1) 1 442.05 84.53% 254.54 48.68% nvm_auto
2) 2 187.51 35.86% 91.66 17.53% nvm
3) 1 75.70 14.48% 64.37 12.31% nvm_ensure_version_installed
Колонка self показывает время, проведённое в каждой функции, исключая вызовы других профилируемых функций. В первую очередь обратите внимание на самые большие значения.
Для измерения реального времени используйте:
/usr/bin/time zsh -i -c exit
Запустите эту команду несколько раз — первый запуск может включать эффекты холодного кеша.
Самые распространённые узкие места
Менеджеры версий языков (nvm, pyenv, conda)
Это главная причина медленного запуска zsh. Одна только стандартная инициализация nvm может добавить 300–500 мс.
Решение: ленивая загрузка. Не инициализируйте эти инструменты до тех пор, пока они действительно не понадобятся.
Для nvm замените стандартный блок инициализации на:
export NVM_DIR="$HOME/.nvm"
nvm() {
unfunction nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm "$@"
}
Использование функции-обёртки вместо алиаса здесь более надёжно. Подход на основе алиасов может сломаться, когда nvm вызывается косвенно (например, скриптом или другой функцией), потому что алиасы раскрываются только в интерактивных позициях команд верхнего уровня. Функция же ведёт себя как настоящая команда в любом контексте.
Если вы используете Oh-My-Zsh, включите плагин nvm с ленивой загрузкой:
zstyle ':omz:plugins:nvm' lazy yes
plugins=(git nvm)
Этот подход сократил время запуска у одного пользователя с 430 мс до 140 мс — улучшение на 70%.
Множественные вызовы compinit
Функция compinit инициализирует систему автодополнения zsh. Она ресурсоёмкая, и фреймворки часто вызывают её несколько раз по ошибке.
Лучшая практика: вызывайте compinit ровно один раз, после всех изменений $fpath.
# СНАЧАЛА добавьте в fpath
fpath=($ZSH_CUSTOM/plugins/zsh-completions/src $fpath)
# ЗАТЕМ инициализируйте автодополнения
autoload -Uz compinit && compinit
Если ваш файл .zcompdump устарел или повреждён, пересоздайте его:
rm -f ~/.zcompdump
compinit
Использование compinit -C пропускает проверки безопасности и работает быстрее, но поймите компромисс перед включением: оно не предупредит вас, если файл автодополнения был изменён или принадлежит другому пользователю.
Discover how at OpenReplay.com.
Слишком много плагинов
Каждый плагин загружает файлы синхронно во время запуска. Безжалостно проверьте список плагинов.
Проверьте, какие плагины вы действительно используете. Плагины github и brew печально известны своей медлительностью. Удалите всё, что не используете еженедельно.
Тяжёлые темы
Сложные темы, которые запрашивают статус git, проверяют сетевые ресурсы или запускают подпроцессы, добавляют заметную задержку.
Если вы используете Powerlevel9k, переключитесь на Powerlevel10k. Это полная замена, которая отрисовывает приглашения в 10–100 раз быстрее. Включите функцию Instant Prompt для мгновенного запуска.
Автоматические проверки обновлений Oh-My-Zsh
Проверка обновлений Oh-My-Zsh выполняется при каждом запуске оболочки и может доминировать во времени запуска. Отключите её:
DISABLE_AUTO_UPDATE="true"
Вы всё ещё можете запускать omz update вручную, когда захотите.
Быстрые победы для ускорения запуска
- Сократите количество плагинов — удалите неиспользуемые плагины из конфигурации.
- Ленивая загрузка менеджеров версий — nvm, pyenv и conda должны загружаться по требованию.
- Вызывайте compinit один раз — после всех изменений fpath.
- Используйте лёгкую тему — или включите Instant Prompt в Powerlevel10k.
- Отключите автообновления — проверяйте обновления вручную.
Как выглядит «быстрый» запуск
Хорошо оптимизированная конфигурация zsh с Oh-My-Zsh должна запускаться за 150–300 мс. Без фреймворка достижимо 50–100 мс. Если у вас больше 500 мс, что-то конкретное не так — и zprof покажет вам, что именно.
Заключение
Не оптимизируйте вслепую. Профилируйте запуск, определите реальные узкие места и применяйте целевые исправления. Большинство разработчиков могут сократить время запуска zsh на 50–80% менее чем за десять минут, просто настроив ленивую загрузку одного менеджера версий и удалив несколько неиспользуемых плагинов.
Не забудьте удалить строки с zprof из вашего .zshrc, когда закончите измерения.
Часто задаваемые вопросы
Нет. Чистая установка zsh запускается так же быстро, как bash, обычно менее чем за 100 миллисекунд. Воспринимаемая медлительность почти всегда возникает из-за того, что загружает ваш .zshrc при запуске, например плагины, темы и менеджеры версий, а не из-за самой оболочки.
На практике нет. Ленивая загрузка означает, что nvm и управляемая им версия Node загружаются при первом запуске nvm, node, npm или npx в сеансе. После этого первого вызова всё работает точно так же, как раньше. Единственное отличие — оболочка запускается быстрее.
Запустите zsh с включённым профилированием, добавив zmodload zsh/zprof в начало и zprof в конец вашего .zshrc. В выводе найдите несколько вызовов рядом с compinit или compdump. Если колонка calls показывает число больше единицы, ваша конфигурация избыточно инициализирует автодополнения.
Не обязательно. Сам Oh-My-Zsh добавляет умеренные накладные расходы. Замедления возникают из-за конкретных плагинов и тем, загружаемых через него. Сокращение списка плагинов, ленивая загрузка менеджеров версий и переход на быструю тему вроде Powerlevel10k обычно снижают время запуска до менее 300 миллисекунд без отказа от фреймворка.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.