Back

Pourquoi zsh est lent au démarrage (et comment y remédier)

Pourquoi zsh est lent au démarrage (et comment y remédier)

Vous ouvrez un nouvel onglet de terminal. Vous attendez. Une seconde passe, puis deux, peut-être trois. Votre invite zsh finit par apparaître. Ce délai frustrant n’est pas la faute du shell — c’est presque toujours votre configuration.

Une installation zsh standard démarre en environ 50 à 100 millisecondes. Lorsque le démarrage s’étend à plusieurs secondes, les coupables sont prévisibles : surcharge du système de complétion, chargement synchrone des plugins, thèmes lourds et gestionnaires de versions de langages comme nvm ou pyenv. Ce guide vous montre comment identifier ce qui est réellement lent et le corriger sans réécrire toute votre configuration.

Points clés à retenir

  • Un zsh standard démarre en 50-100 ms. Les délais de plusieurs secondes proviennent de votre .zshrc, pas du shell lui-même.
  • Utilisez zsh/zprof et /usr/bin/time zsh -i -c exit pour identifier les véritables goulots d’étranglement avant de modifier quoi que ce soit.
  • Les gestionnaires de versions de langages (nvm, pyenv, conda) sont les coupables les plus courants — chargez-les en lazy-loading pour des gains immédiats.
  • Appelez compinit exactement une fois, réduisez les plugins inutilisés et utilisez un thème léger pour gagner encore du temps de démarrage.

Profilez avant d’optimiser

Deviner fait perdre du temps. Zsh inclut un profileur intégré qui révèle exactement où va votre temps de démarrage.

Ajoutez ceci à la première ligne de votre ~/.zshrc :

zmodload zsh/zprof

Ajoutez ceci à la dernière ligne :

zprof

Ouvrez un nouveau terminal. Vous verrez une sortie comme celle-ci :

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

La colonne self indique le temps passé dans chaque fonction en excluant les appels à d’autres fonctions profilées. Ciblez d’abord les plus grands nombres.

Pour une mesure du temps réel, utilisez :

/usr/bin/time zsh -i -c exit

Exécutez cette commande plusieurs fois — la première invocation peut inclure des effets de cache froid.

Les goulots d’étranglement les plus courants

Gestionnaires de versions de langages (nvm, pyenv, conda)

Ce sont la principale cause de démarrage lent de zsh. L’initialisation par défaut de nvm seule peut ajouter 300 à 500 ms.

La solution : le lazy-loading. N’initialisez pas ces outils tant que vous ne les appelez pas réellement.

Pour nvm, remplacez le bloc d’initialisation standard par :

export NVM_DIR="$HOME/.nvm"

nvm() {
  unfunction nvm
  [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
  nvm "$@"
}

L’utilisation d’une fonction wrapper plutôt qu’un alias est plus robuste ici. Une approche basée sur les alias peut échouer lorsque nvm est invoqué indirectement (par exemple, par un script ou une autre fonction), car les alias ne sont développés que dans des positions de commande interactives de premier niveau. Une fonction, en revanche, se comporte comme une vraie commande dans tous les contextes.

Si vous utilisez Oh-My-Zsh, activez le plugin nvm avec le lazy-loading :

zstyle ':omz:plugins:nvm' lazy yes
plugins=(git nvm)

Cette approche a réduit le démarrage d’un utilisateur de 430 ms à 140 ms — une amélioration de 70 %.

compinit appelé plusieurs fois

La fonction compinit initialise le système de complétion de zsh. Elle est coûteuse, et les frameworks l’appellent souvent plus d’une fois par accident.

Bonne pratique : Appelez compinit exactement une fois, après que toutes les modifications de $fpath sont terminées.

# Ajoutez d'ABORD à fpath
fpath=($ZSH_CUSTOM/plugins/zsh-completions/src $fpath)

# PUIS initialisez les complétions
autoload -Uz compinit && compinit

Si votre fichier .zcompdump est obsolète ou corrompu, régénérez-le :

rm -f ~/.zcompdump
compinit

L’utilisation de compinit -C ignore les vérifications de sécurité et est plus rapide, mais comprenez le compromis avant de l’activer : il ne vous avertira pas si un fichier de complétion a été altéré ou appartient à un autre utilisateur.

Trop de plugins

Chaque plugin charge des fichiers de manière synchrone au démarrage. Auditez votre liste de plugins sans pitié.

Vérifiez quels plugins vous utilisez réellement. Les plugins github et brew sont notoirement lents. Supprimez tout ce que vous n’utilisez pas chaque semaine.

Thèmes lourds

Les thèmes complexes qui interrogent le statut git, vérifient les ressources réseau ou exécutent des sous-processus ajoutent une latence notable.

Si vous utilisez Powerlevel9k, passez à Powerlevel10k. C’est un remplacement direct qui affiche les invites 10 à 100 fois plus rapidement. Activez sa fonctionnalité Instant Prompt pour un démarrage perçu comme instantané.

Vérifications de mise à jour automatique d’Oh-My-Zsh

La vérification de mise à jour d’Oh-My-Zsh s’exécute à chaque lancement de shell et peut dominer le temps de démarrage. Désactivez-la :

DISABLE_AUTO_UPDATE="true"

Vous pouvez toujours exécuter omz update manuellement quand vous le souhaitez.

Gains rapides pour un démarrage plus rapide

  1. Réduisez le nombre de plugins – Supprimez les plugins inutilisés de votre configuration.
  2. Chargez les gestionnaires de versions en lazy-loading – nvm, pyenv et conda doivent se charger à la demande.
  3. Appelez compinit une seule fois – Après que toutes les modifications de fpath sont terminées.
  4. Utilisez un thème léger – Ou activez l’Instant Prompt de Powerlevel10k.
  5. Désactivez les mises à jour automatiques – Vérifiez les mises à jour manuellement à la place.

À quoi ressemble réellement la « rapidité »

Une configuration zsh bien optimisée avec Oh-My-Zsh devrait démarrer en 150 à 300 ms. Sans framework, 50 à 100 ms est réalisable. Si vous dépassez 500 ms, quelque chose de spécifique ne va pas — et zprof vous montrera quoi.

Conclusion

N’optimisez pas à l’aveugle. Profilez votre démarrage, identifiez les véritables goulots d’étranglement et appliquez des correctifs ciblés. La plupart des développeurs peuvent réduire leur temps de démarrage zsh de 50 à 80 % en moins de dix minutes en chargeant un gestionnaire de versions en lazy-loading et en supprimant quelques plugins inutilisés.

N’oubliez pas de retirer les lignes zprof de votre .zshrc lorsque vous avez fini de mesurer.

FAQ

Non. Une installation zsh standard démarre aussi rapidement que bash, généralement en moins de 100 millisecondes. La lenteur perçue provient presque toujours de ce que votre .zshrc charge au démarrage, comme les plugins, les thèmes et les gestionnaires de versions, et non du shell lui-même.

Pas en pratique. Le lazy-loading signifie que nvm et sa version Node gérée sont chargés la première fois que vous exécutez nvm, node, npm ou npx dans une session. Après cet appel initial, tout fonctionne exactement comme avant. La seule différence est que le shell démarre plus rapidement.

Exécutez zsh avec le profilage activé en ajoutant zmodload zsh/zprof en haut et zprof en bas de votre .zshrc. Dans la sortie, recherchez plusieurs appels à côté de compinit ou compdump. Si la colonne calls affiche un nombre supérieur à un, votre configuration initialise les complétions de manière redondante.

Pas nécessairement. Oh-My-Zsh lui-même ajoute une surcharge modeste. Les ralentissements proviennent de plugins et thèmes spécifiques chargés à travers lui. Réduire votre liste de plugins, charger les gestionnaires de versions en lazy-loading et passer à un thème rapide comme Powerlevel10k ramènent généralement le démarrage bien en dessous de 300 millisecondes sans abandonner le 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.

OpenReplay