Framework DevTools: Vue & Angular — Debugging

Framework DevTools: Vue & Angular React DevTools bukan satu-satunya — Vue dan Angular punya browser extension setara yang penting dikuasai kalau bekerja di…

Vue dan Angular, sama seperti React, punya extension DevTools sendiri. Extension itu menambah tab di DevTools browser yang mengerti komponen: alih-alih tumpukan <div>, kamu melihat pohon komponen dan state tiap komponen. Bayangin sebuah rumah. Panel Elements itu melihat rumah dari luar: bata, cat, jendela. Framework DevTools itu denahnya: nama tiap ruangan, dan isi lemari di tiap ruangan.

🧪 Tebakan cepat: Di Profiler Angular DevTools, komponen ProductList tercatat dicek di 5 change detection cycle, tapi input-nya cuma berubah di 2 cycle. Berapa pengecekan yang sia-sia, dan apa sarannya? Jawabannya ada di bagian "Profiler: siapa yang kerja sia-sia".

Pasang extension yang tepat

Framework Nama extension Catatan
React React Developer Tools Chrome, Firefox, Edge
Vue Vue.js devtools Chrome dan browser Chromium lain, juga Firefox. Versi 7 ke atas cuma untuk Vue 3; app Vue 2 butuh extension versi lama (v6). Ada juga plugin Vite vite-plugin-vue-devtools.
Angular Angular DevTools Chrome dan Firefox. Cuma jalan di development build.

Setelah dipasang, buka app-nya di mode development, lalu buka DevTools: muncul tab Vue atau Angular. Di production build keduanya mati secara bawaan. Kalau tab-nya gak muncul, cek dulu build-nya. Untuk Angular, Augury adalah alat lama yang sudah gak dikembangkan, pakai Angular DevTools.

Nama resminya ditulis persis, huruf besar-kecilnya juga. Di latihan, pickDevTools cukup memetakan nama framework ke nama extension:

function pickDevTools(framework) {
  const tools = {
    react: "React Developer Tools",
    vue: "Vue.js devtools",
    angular: "Angular DevTools",
  }
  return tools[framework]
}

Components: pohon komponen dan state-nya

Tab Components menampilkan komponen sebagai pohon. Ini app di latihan dan di Lab:

App               { user: null }
├─ Header         { loggedIn: false }
└─ Main           { view: "list" }
   └─ ProductList { items: [], loading: true }

Di latihan, kamu menulis pencarian yang mirip: telusuri pohon dari akar, dan kembalikan jalur ke komponen pertama yang state-nya cocok.

function findComponentByState(tree, predicate) {
  function search(node, path) {
    const here = [...path, node.name]          // jalur sampai node ini
    if (predicate(node.state)) return here
    for (const child of node.children || []) {
      const found = search(child, here)
      if (found) return found                  // berhenti di yang pertama cocok
    }
    return null
  }
  return search(tree, []) || []                // gak ada yang cocok: array kosong
}

findComponentByState(tree, (s) => s.loading === true).join(">") // "App>Main>ProductList"
Dikunjungi loading === true? Jalur
App tidak App
Header tidak, gak punya anak App > Header
Main tidak App > Main
ProductList ya App > Main > ProductList

Profiler: siapa yang kerja sia-sia

Change detection adalah proses Angular mengecek apakah tampilan sebuah komponen perlu diperbarui. Satu putaran pengecekan disebut cycle. Dengan strategi Default, tiap cycle mengecek semua komponen. Dengan OnPush, komponen cuma dicek kalau input-nya dapat reference baru, ada event dari dalamnya, atau signal yang dibacanya berubah.

Di tab Profiler, klik Start recording, pakai app-nya, lalu stop. Tiap batang adalah satu change detection cycle, makin tinggi makin lama. Klik sebuah batang untuk melihat komponen mana saja yang dicek di cycle itu.

Cycle Durasi Input berubah? Pengecekan
1 2 ms ya perlu
2 3 ms tidak sia-sia
3 2 ms tidak sia-sia
4 4 ms tidak sia-sia
5 3 ms ya perlu

Ada 3 pengecekan sia-sia dari 5 cycle, lebih dari separuh (2,5), jadi sarannya OnPush. Itu jawaban tebakannya. Rata-rata durasinya (2 + 3 + 2 + 4 + 3) / 5 = 2,8, dibulatkan jadi 3.

function analyzeChangeDetection(cycles) {
  const unnecessaryChecks = cycles.filter((c) => c.checked && !c.inputChanged).length
  const avgDuration = Math.round(cycles.reduce((sum, c) => sum + c.duration, 0) / cycles.length)
  const recommendation = unnecessaryChecks > cycles.length / 2 ? "OnPush" : "OK"
  return { unnecessaryChecks, avgDuration, recommendation }
}

Di Vue, tempatnya tab Timeline: dia mencatat event performa, termasuk berapa lama tiap komponen render dan update. Kalau ProductList render ulang terus padahal datanya sama, biasanya parent mengirim array baru tiap kali dia render:

// Di template Main: :items="products.filter((p) => p.active)"
// filter membuat array baru tiap Main render, jadi prop-nya selalu "berubah"

const activeProducts = computed(() => products.value.filter((p) => p.active))
// Di template Main: :items="activeProducts"

computed menyimpan hasilnya dan memberi array yang sama selama products gak berubah, jadi ProductList gak perlu render ulang. Untuk data yang sangat besar, shallowRef membuat Vue gak melacak isinya satu per satu.

Fitur khas masing-masing

🎯 Alur debugging pakai framework DevTools

  1. Ulangi bug-nya sampai terjadi lagi.
  2. Buka Components, cari komponennya, baca props dan state-nya.
  3. Edit state langsung untuk menguji dugaan.
  4. Kalau masalahnya lambat, rekam di Profiler (Angular) atau Timeline (Vue).
  5. Kalau datanya dipakai bersama, cek tab store (Pinia).
  6. Masih buntu? Pasang breakpoint di panel Sources.

⚠️ Jebakan yang sering ketemu

TL;DR: Nama extension resminya React Developer Tools, Vue.js devtools (versi 7 ke atas untuk Vue 3), dan Angular DevTools, dan semuanya bekerja di development build. Tab Components menampilkan pohon komponen beserta props dan state-nya, yang bisa diedit langsung; di latihan, findComponentByState menelusuri pohon dari akar dan mengembalikan jalur App>Main>ProductList, atau [] kalau gak ada yang cocok. Profiler Angular mencatat change detection cycle: pengecekan saat input gak berubah itu sia-sia, dan kalau jumlahnya lebih dari separuh (3 dari 5), sarannya OnPush. Di Vue, Timeline menunjukkan render yang berlebihan, biasanya karena parent mengirim array baru tiap render, dan computed memperbaikinya. Injector Tree cuma ada di Angular DevTools, karena Angular punya DI bertingkat.

Yang akan kamu pelajari