Mengukur dan mengoptimalkan startup Zsh: benchmark dengan time zsh -i -c exit, lazy-load plugin dan function, cache completion dengan compinit -C, menghindari perintah eksternal di prompt dengan caching vcs_info, serta memakai hash untuk lookup perintah yang lebih cepat

Setelah di episode 20 kalian memahami peta rilis Zsh, pada episode ini kita membahas hal yang paling sering dikeluhkan pengguna yang baru pindah dari bash atau fish: kecepatan startup. Shell yang butuh 500 ms untuk muncul terasa berat — apalagi saat membuka banyak terminal sekaligus.
Kabar baiknya: Zsh yang dikonfigurasi dengan benar bisa start di bawah 100 ms, bahkan mendekati 20-30 ms. Episode ini membahas cara mengukur startup, lalu mengoptimalkannya berlapis: lazy-load plugin, cache completion, prompt yang tidak memanggil perintah eksternal, dan lookup hash.
Ukuran dasar: waktu dari shell mulai sampai prompt siap.
time zsh -i -c exit-i (interactive) memaksa membaca .zshrc; -c exit langsung keluar. Output time menunjukkan total.
zsh -i -c exit 0.02s user 0.01s system 0% cpu 0.032 totalUntuk pengukuran yang lebih stabil, ulangi beberapa kali dan ambil rata-ratanya:
for i in {1..10}; do time zsh -i -c exit; doneDiagnostik per bagian startup — ukur waktu tiap segmen .zshrc:
# Di awal .zshrc:
zmodload zsh/datetime
typeset -g START_TIME=$EPOCHSECONDS
# Di akhir .zshrc:
print "Startup: $((EPOCHSECONDS - START_TIME)) detik"Urutan penyebab paling umum:
plugins=(...) setiap startup.compinit reindexing — memindai ratusan function _* setiap kali.git status, kubectl config di setiap prompt..zshrc — eval "$(zoxide init zsh)", eval "$(fzf --zsh)" yang berat.# Bungkus perintah eksternal dengan timing:
time eval "$(zoxide init zsh)"
time eval "$(fzf --zsh)"Prinsip: jangan memuat plugin yang belum dipakai. Zinit menyediakan ice wait'0' (muat saat idle) dan lazy-loading per-perintah.
# Load segera (dibutuhkan setiap prompt)
zinit light zsh-users/zsh-autosuggestions
# Load saat idle — tidak menghambat prompt
zinit ice wait'0' lucid
zinit light zsh-users/zsh-syntax-highlighting
# Load hanya saat perintah fzf dipanggil
zinit ice wait'0' lucid as"program" pick"bin/fzf" make
zinit light junegunn/fzf
# Alias yang lazy — function dipanggil saat pertama dipakai
lazy_command() {
# ... definisi, baru eval saat dipanggil
}Konsep yang sama untuk function: gunakan autoload (episode 10) agar function tidak dimuat sampai benar-benar dipanggil.
compinit tanpa argumen memindai semua direktori fpath setiap startup. compinit -C melewati pemindaian dan langsung memuat cache:
# Buat cache sekali:
autoload -Uz compinit
compinit -d "$HOME/.zcompdump"
# Di startup normal:
autoload -Uz compinit
compinit -C -d "$HOME/.zcompdump"Perbedaan: compinit -C membaca dump yang sudah ada tanpa reindex. Cache perlu di-refresh saat ada plugin baru — hapus file dump, atau jalankan compinit penuh sesekali:
rm ~/.zcompdump
# jalankan shell baru → compinit penuh → cache baruWarning
compinit -C hemat waktu tapi bisa melewatkan completion baru jika cache basi. Aturan aman: gunakan -C untuk penggunaan sehari-hari, dan refresh cache saat menambah plugin baru atau setelah update Oh My Zsh/zinit.
Prompt yang memanggil git status atau kubectl di setiap tampilan adalah pembunuh startup dan sumber lag. vcs_info (episode 7) sudah efisien, tetapi check-for-changes tetap memanggil git.
Strategi caching:
precmd() {
vcs_info
# Simpan hasil — jangan panggil git lagi di sini
GIT_BRANCH="${vcs_info_msg_0_}"
}autoload -Uz vcs_info
precmd() {
vcs_info
}
zstyle ':vcs_info:git:*' formats ' %F{green}%b%f'
zstyle ':vcs_info:*:*' check-for-changes false # JANGAN panggil git ekstra
PROMPT='%F{blue}%~%f${vcs_info_msg_0_}%# 'Jika tetap butuh informasi git yang segar, batasi frekuensinya dengan timestamp:
precmd() {
local now=$EPOCHSECONDS
if (( now - LAST_GIT_CHECK > 10 )); then
LAST_GIT_CHECK=$now
# panggil git hanya jika repo terdeteksi
fi
}Zsh punya tabel hash internal — memetakan nama perintah ke path binary. Lookup yang tidak di-hash memakai PATH scan; yang sudah di-hash langsung:
hash
# ls=/usr/bin/ls cat=/usr/bin/cat ...Prefill hash untuk perintah yang sering dipakai:
hash -r
hash -d projects=~/Documents/projects # direktori shortcut: ~projectshash -d nama=path membuat shortcut direktori — cd ~projects langsung mengarah ke path itu. Berguna untuk sering masuk ke direktori panjang tanpa menulis ulang path.
Tip
Satu lagi cara lookup lebih cepat: hash -d untuk direktori dan alias/function untuk perintah. Bila sebuah perintah dipanggil ribuan kali di skrip, memastikan path-nya sudah di-hash (bukan scan PATH tiap kali) menghemat waktu nyata.
Urutan ini bekerja berlapis — setiap langkah bisa menurunkan puluhan milidetik, dan hasil akhir sering di bawah 50 ms.
time zsh -i -c exit.compinit -C dengan cache basi — completion baru tidak muncul; refresh cache saat menambah plugin.check-for-changes true di repo besar — setiap prompt memanggil git di direktori raksasa; matikan atau throttle.Inti yang harus dibawa pulang:
time zsh -i -c exit; target ideal di bawah 100 ms.wait'0' dan autoload.compinit -C + dump cache mempercepat completion; refresh saat plugin baru.vcs_info dan throttle.hash -d untuk shortcut direktori dan lookup cepat.Di episode 22, episode terakhir series ini, kita akan membahas ekosistem, alternatif & refleksi akhir — membandingkan Zsh dengan Bash, fish, nushell, dan Nix shell, kapan memilih masing-masing, rekap lengkap episode 0-21, checklist production, dan sumber belajar resmi. Pastikan tetap semangat!