Belajar Zsh - Performance & Startup Optimization
Series/Belajar Zsh/Episode 21
Episode 21 of 23

Belajar Zsh - Performance & Startup Optimization

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

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

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.

Mengukur Startup

Ukuran dasar: waktu dari shell mulai sampai prompt siap.

Benchmark startup
time zsh -i -c exit

-i (interactive) memaksa membaca .zshrc; -c exit langsung keluar. Output time menunjukkan total.

Contoh output
zsh -i -c exit  0.02s user 0.01s system 0% cpu 0.032 total

Untuk pengukuran yang lebih stabil, ulangi beberapa kali dan ambil rata-ratanya:

Rata-rata 10 run
for i in {1..10}; do time zsh -i -c exit; done

Diagnostik per bagian startup — ukur waktu tiap segmen .zshrc:

Profil startup manual
# Di awal .zshrc:
zmodload zsh/datetime
typeset -g START_TIME=$EPOCHSECONDS
 
# Di akhir .zshrc:
print "Startup: $((EPOCHSECONDS - START_TIME)) detik"

Penyebab Startup Lambat: Klasik

Urutan penyebab paling umum:

  1. Plugin di-load semuanya — Oh My Zsh memuat semua plugin di plugins=(...) setiap startup.
  2. compinit reindexing — memindai ratusan function _* setiap kali.
  3. Prompt memanggil perintah eksternalgit status, kubectl config di setiap prompt.
  4. Perintah eksternal di .zshrceval "$(zoxide init zsh)", eval "$(fzf --zsh)" yang berat.
Deteksi kambing hitam
# Bungkus perintah eksternal dengan timing:
time eval "$(zoxide init zsh)"
time eval "$(fzf --zsh)"

Optimasi 1: Lazy-Load Plugin

Prinsip: jangan memuat plugin yang belum dipakai. Zinit menyediakan ice wait'0' (muat saat idle) dan lazy-loading per-perintah.

~/.zshrc (zinit lazy)
# 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.

Optimasi 2: Cache Completion dengan compinit -C

compinit tanpa argumen memindai semua direktori fpath setiap startup. compinit -C melewati pemindaian dan langsung memuat cache:

Cache compinit
# 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:

Refresh cache
rm ~/.zcompdump
# jalankan shell baru → compinit penuh → cache baru

Warning

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.

Optimasi 3: Prompt yang Tidak Memanggil Perintah Eksternal

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:

Cache status git di precmd
precmd() {
    vcs_info
    # Simpan hasil — jangan panggil git lagi di sini
    GIT_BRANCH="${vcs_info_msg_0_}"
}
~/.zshrc (prompt hemat)
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:

Throttle git call
precmd() {
    local now=$EPOCHSECONDS
    if (( now - LAST_GIT_CHECK > 10 )); then
        LAST_GIT_CHECK=$now
        # panggil git hanya jika repo terdeteksi
    fi
}

Optimasi 4: hash untuk Lookup Cepat

Zsh punya tabel hash internal — memetakan nama perintah ke path binary. Lookup yang tidak di-hash memakai PATH scan; yang sudah di-hash langsung:

Lihat hash aktif
hash
# ls=/usr/bin/ls  cat=/usr/bin/cat  ...

Prefill hash untuk perintah yang sering dipakai:

Prefill hash
hash -r
hash -d projects=~/Documents/projects      # direktori shortcut: ~projects

hash -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.

Ringkasan Alur Optimasi

100%

Urutan ini bekerja berlapis — setiap langkah bisa menurunkan puluhan milidetik, dan hasil akhir sering di bawah 50 ms.

Common Pitfalls

  • Optimasi sebelum ukur — tanpa benchmark, tidak tahu bagian mana yang harus dibenahi; selalu mulai dari 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.
  • Lazy-load berlebihan — plugin yang dipakai setiap perintah justru lebih lambat di-load lazy; gunakan untuk yang benar-benar jarang.

Penutup

Inti yang harus dibawa pulang:

  • Ukur dulu: time zsh -i -c exit; target ideal di bawah 100 ms.
  • Lazy-load plugin dengan zinit ice wait'0' dan autoload.
  • compinit -C + dump cache mempercepat completion; refresh saat plugin baru.
  • Prompt jangan memanggil git/kubectl setiap tampil; cache dengan 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!