Flame Graphs & CPU Profiling — Debugging

Jika aplikasi lambat tapi tidak jelas bagian mana, flame graph adalah alat diagnosa terbaik. Satu gambar langsung menunjukkan function mana yang menghabiskan pa

Jika aplikasi lambat tapi tidak jelas bagian mana, flame graph adalah alat diagnosa terbaik. Satu gambar langsung menunjukkan function mana yang menghabiskan paling banyak waktu CPU.

Cara baca flame graph:

┌──────────────────────────────────────────────┐
│ main (60ms)                                  │
├──────────────┬───────────────────────────────┤
│ renderPage   │ fetchUsers (40ms)             │
│ (20ms)       ├──────────┬────────────────────┤
├──────────────┤ parseJSON│ transformUsers (30)│
│ layout (15)  │ (5ms)    ├──────────┬─────────┤
├────┬─────────┤          │ normalize│ validate│
│ dom│ paint   │          │ (15ms)   │ (10ms)  │
└────┴─────────┴──────────┴──────────┴─────────┘

Aturan baca:

Cara generate di browser:

Chrome DevTools → Performance tab → Record → interact → Stop
→ "Bottom-Up" view untuk list fungsi terberat
→ "Call Tree" view untuk flame-graph-style
→ "Flame Chart" section di bawah untuk visualisasi horizontal

Cara generate di Node.js:

# Built-in profiler
node --prof app.js
# Jalankan workload, lalu:
node --prof-process isolate-*.log > profile.txt

# Better: clinic.js
npx clinic flame -- node app.js
# hasil: flamegraph.html

# Alternative: 0x
npx 0x app.js

Yang perlu dicari:

1. Plateau lebar di bagian atas (self time tinggi)

│ calculateSomething (45ms self) │

Fungsi ini sendiri yang lambat, bukan yang dipanggilnya. Optimasi langsung di sini.

2. Stack dalam + kepala kecil (waterfall) Fungsi manggil fungsi manggil fungsi. Bukan lambat per se, tapi indikator over-engineering atau middleware chain terlalu dalam.

3. Function yang tidak diharapkan muncul

CPU profiler vs sampling profiler:

Jenis Cara kerja Akurasi Overhead
Sampling Snapshot stack tiap X ms Approximate Rendah
Instrumentation Hook masuk/keluar fungsi Exact Tinggi

Chrome DevTools pakai sampling (1ms default). Cukup akurat untuk 99% kasus.

Membedakan flame graph vs icicle chart:

Chrome DevTools pakai icicle (root di atas). Brendan Gregg's original flame graph root di bawah. Sama konsep, hanya orientasi.

Kesalahan interpretasi umum:

❌ "Function paling lebar pasti bottleneck" — bisa jadi lebar karena banyak panggilan (total time), tapi self time kecil.

✅ Selalu cek self time vs total time. Self time tinggi = fungsi ini lambat. Total time tinggi tapi self time rendah = fungsi ini hanya delegate ke fungsi lain.

Workflow optimasi tipikal:

  1. Reproduce slow scenario dengan ukuran data realistik
  2. Record profile
  3. Identifikasi top 3 fungsi dengan self time tertinggi
  4. Optimasi yang paling tinggi (hukum Amdahl: fokus ke yang paling berat)
  5. Re-record untuk verify improvement
  6. Ulangi jika masih lambat

Jangan optimasi tanpa profil! Intuisi developer sering salah tentang bagian mana yang lambat.