Por Que o zsh É Lento para Iniciar (e Como Corrigir)
Você abre uma nova aba do terminal. Você espera. Um segundo passa, depois dois, talvez três. Seu prompt do zsh finalmente aparece. Esse atraso frustrante não é culpa do shell—quase sempre é da sua configuração.
Uma instalação vanilla do zsh inicia em aproximadamente 50–100 milissegundos. Quando a inicialização aumenta para vários segundos, os culpados são previsíveis: sobrecarga do sistema de completação, carregamento síncrono de plugins, temas pesados e gerenciadores de versão de linguagem como nvm ou pyenv. Este guia mostra como identificar o que está realmente lento e corrigir sem reescrever toda a sua configuração.
Pontos-Chave
- Um zsh padrão inicia em 50–100ms. Atrasos de vários segundos vêm do seu
.zshrc, não do shell em si. - Use
zsh/zprofe/usr/bin/time zsh -i -c exitpara identificar os verdadeiros gargalos antes de mudar qualquer coisa. - Gerenciadores de versão de linguagem (nvm, pyenv, conda) são os infratores mais comuns—carregue-os sob demanda para ganhos imediatos.
- Chame
compinitexatamente uma vez, remova plugins não utilizados e use um tema leve para reduzir ainda mais o tempo de inicialização.
Faça o Profile Antes de Otimizar
Adivinhar desperdiça tempo. O Zsh inclui um profiler integrado que revela exatamente onde vai o tempo de inicialização.
Adicione isso à primeira linha do seu ~/.zshrc:
zmodload zsh/zprof
Adicione isso à última linha:
zprof
Abra um novo terminal. Você verá uma saída como esta:
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
A coluna self mostra o tempo gasto em cada função excluindo chamadas a outras funções perfiladas. Foque primeiro nos maiores números.
Para medição de tempo real, use:
/usr/bin/time zsh -i -c exit
Execute isso várias vezes—a primeira invocação pode incluir efeitos de cache frio.
Os Gargalos Mais Comuns
Gerenciadores de Versão de Linguagem (nvm, pyenv, conda)
Estes são a maior causa isolada de inicialização lenta do zsh. Apenas a inicialização padrão do nvm pode adicionar 300–500ms.
A solução: carregamento sob demanda (lazy loading). Não inicialize essas ferramentas até que você realmente as chame.
Para o nvm, substitua o bloco de inicialização padrão por:
export NVM_DIR="$HOME/.nvm"
nvm() {
unfunction nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm "$@"
}
Usar uma função wrapper em vez de um alias é mais robusto aqui. Uma abordagem baseada em alias pode quebrar quando o nvm é invocado indiretamente (por exemplo, por um script ou outra função), porque aliases são expandidos apenas em posições de comando de nível superior interativas. Uma função, por outro lado, se comporta como um comando real em todos os contextos.
Se você usa Oh-My-Zsh, habilite o plugin nvm com carregamento sob demanda:
zstyle ':omz:plugins:nvm' lazy yes
plugins=(git nvm)
Essa abordagem reduziu a inicialização de um usuário de 430ms para 140ms—uma melhoria de 70%.
compinit Chamado Múltiplas Vezes
A função compinit inicializa o sistema de completação do zsh. É cara, e frameworks frequentemente a chamam mais de uma vez por acidente.
Melhor prática: Chame compinit exatamente uma vez, após todas as modificações do $fpath estarem completas.
# Adicione ao fpath PRIMEIRO
fpath=($ZSH_CUSTOM/plugins/zsh-completions/src $fpath)
# DEPOIS inicialize as completações
autoload -Uz compinit && compinit
Se seu arquivo .zcompdump estiver desatualizado ou corrompido, regenere-o:
rm -f ~/.zcompdump
compinit
Usar compinit -C pula verificações de segurança e é mais rápido, mas entenda o trade-off antes de habilitá-lo: não avisará se um arquivo de completação foi adulterado ou pertence a outro usuário.
Discover how at OpenReplay.com.
Muitos Plugins
Cada plugin carrega arquivos de forma síncrona durante a inicialização. Audite sua lista de plugins sem piedade.
Verifique quais plugins você realmente usa. Os plugins github e brew são notoriamente lentos. Remova qualquer coisa que você não use semanalmente.
Temas Pesados
Temas complexos que consultam status do git, verificam recursos de rede ou executam subprocessos adicionam latência perceptível.
Se você usa Powerlevel9k, mude para Powerlevel10k. É um substituto direto que renderiza prompts 10–100x mais rápido. Habilite seu recurso Instant Prompt para inicialização percebida como instantânea.
Verificações de Atualização Automática do Oh-My-Zsh
A verificação de atualização do Oh-My-Zsh é executada em cada inicialização do shell e pode dominar o tempo de inicialização. Desabilite-a:
DISABLE_AUTO_UPDATE="true"
Você ainda pode executar omz update manualmente quando quiser.
Ganhos Rápidos para Inicialização Mais Rápida
- Reduza a contagem de plugins – Remova plugins não utilizados da sua configuração.
- Carregue gerenciadores de versão sob demanda – nvm, pyenv e conda devem carregar sob demanda.
- Chame compinit uma vez – Após todas as modificações do fpath estarem concluídas.
- Use um tema leve – Ou habilite o Instant Prompt do Powerlevel10k.
- Desabilite atualizações automáticas – Verifique atualizações manualmente.
Como “Rápido” Realmente Parece
Uma configuração zsh bem otimizada com Oh-My-Zsh deve iniciar em 150–300ms. Sem um framework, 50–100ms é alcançável. Se você estiver acima de 500ms, algo específico está errado—e o zprof mostrará o quê.
Conclusão
Não otimize às cegas. Faça o profile da sua inicialização, identifique os verdadeiros gargalos e aplique correções direcionadas. A maioria dos desenvolvedores pode reduzir o tempo de inicialização do zsh em 50–80% em menos de dez minutos carregando um gerenciador de versão sob demanda e removendo alguns plugins não utilizados.
Lembre-se de remover as linhas do zprof do seu .zshrc quando terminar de medir.
Perguntas Frequentes
Não. Uma instalação básica do zsh inicia tão rápido quanto o bash, tipicamente em menos de 100 milissegundos. A lentidão percebida quase sempre vem do que seu .zshrc carrega na inicialização, como plugins, temas e gerenciadores de versão, não do shell em si.
Não na prática. Carregamento sob demanda significa que o nvm e sua versão gerenciada do Node são carregados na primeira vez que você executa nvm, node, npm ou npx em uma sessão. Após essa chamada inicial, tudo funciona exatamente como antes. A única diferença é que o shell inicia mais rápido.
Execute o zsh com profiling habilitado adicionando zmodload zsh/zprof no topo e zprof no final do seu .zshrc. Na saída, procure por múltiplas chamadas ao lado de compinit ou compdump. Se a coluna calls mostrar um número maior que um, sua configuração está inicializando completações de forma redundante.
Não necessariamente. O Oh-My-Zsh em si adiciona sobrecarga modesta. As lentidões vêm de plugins e temas específicos carregados através dele. Reduzir sua lista de plugins, carregar gerenciadores de versão sob demanda e mudar para um tema rápido como Powerlevel10k geralmente trazem a inicialização para bem abaixo de 300 milissegundos sem abandonar o framework.
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.