Setiap kali kita menjalankan node app.mjs, ada satu komponen yang membaca, menerjemahkan, dan mengeksekusi kode JavaScript kita: V8. Mesin ini dipilih Ryan Dahl pada 2009 dan sampai sekarang tetap menjadi jantung Node.js. Memahami peran V8 membantu kita menjawab pertanyaan praktis: dari mana Node.js mendukung fitur JavaScript terbaru, mengapa pola kode tertentu berjalan lebih cepat, dan apa sebenarnya yang Node.js tambahkan di atas mesin tersebut. Chapter ini membedah peran V8 dan alur kerjanya secara bertahap.

V8, Mesin di Jantung Node.js #

V8 adalah mesin JavaScript (JavaScript engine) open-source buatan Google yang ditulis dalam bahasa C++. Mesin yang sama mengeksekusi JavaScript di browser Chrome, sehingga kode JavaScript yang kita tulis untuk Node.js dievaluasi oleh teknologi identik dengan yang dipakai ratusan juta pengguna Chrome. Tiga tanggung jawab utama V8: mengompilasi kode JavaScript menjadi instruksi yang bisa dijalankan prosesor, mengeksekusi instruksi tersebut, dan mengelola memori melalui mekanisme garbage collection yang otomatis membersihkan object yang tidak lagi terpakai.

Meski sentral, V8 tidak bekerja sendirian. Node.js menyusun empat lapisan komponen berikut:

KomponenPeran
V8Menjalankan JavaScript: parsing, kompilasi, eksekusi, dan garbage collection
libuvEvent loop, I/O asynchronous, dan thread pool untuk berkas, jaringan, serta timer
Bindings C++Jembatan yang menghubungkan fungsi V8 dengan kemampuan sistem operasi
Core modulesAPI siap pakai seperti node:fs, node:http, dan node:path

V8 sama sekali tidak tahu cara membaca berkas atau menerima koneksi jaringan — hal tersebut diurus oleh libuv dan bindings, lalu dibungkus menjadi core modules yang bisa kita panggil dari JavaScript. Inilah sebabnya document dan API DOM tidak ada di Node.js: keduanya adalah kemampuan yang disediakan browser, bukan V8.

Dari Kode Sumber ke Instruksi Mesin #

V8 tidak menerjemahkan JavaScript baris demi baris seperti halnya membaca naskah. Mesin ini menempuh alur bertingkat agar waktu mulai program tetap singkat, namun performa jangka panjangnya tetap tinggi:

  1. Parsing — V8 membaca teks sumber, memecahnya menjadi token, lalu menyusun abstract syntax tree (AST), representasi berbentuk pohon dari struktur kode kita. Kesalahan sintaks terdeteksi pada tahap ini.
  2. Kompilasi bytecode — AST diterjemahkan menjadi bytecode ringkas oleh interpreter Ignition, lalu bytecode langsung dieksekusi. Tahap ini membuat waktu mulai program tetap pendek.
  3. Pengumpulan umpan balik — selama bytecode berjalan, V8 mencatat pola nyata: tipe data yang lewat, bentuk object yang dipakai, dan cabang kode yang sering dieksekusi.
  4. Optimasi (JIT) — fungsi yang sangat sering dieksekusi (“panas”) dikompilasi ulang menjadi kode mesin asli oleh lapisan optimasi seperti Sparkplug, Maglev, dan TurboFan, berdasarkan umpan balik yang terkumpul. Teknik kompilasi saat program berjalan inilah yang disebut just-in-time compilation (JIT).
  5. Deoptimisasi — bila asumsi optimasi ternyata meleset (misalnya tipe data berubah), V8 membuang versi teroptimasi dan kembali ke bytecode. Proses bolak-balik ini normal, tetapi pola kode yang tidak konsisten membuatnya sering terjadi.

Melihat V8 Bekerja #

Kode berikut memakai fitur JavaScript modern — class, arrow function, dan template literal — lalu mencetak versi V8 yang mengeksekusinya:

js
class Bilangan {
  constructor(nilai) {
    this.nilai = nilai;
  }

  ganda() {
    return this.nilai * 2;
  }
}

const hasil = [1, 2, 3, 4, 5].map((n) => new Bilangan(n).ganda());
console.log(`Hasil map: ${hasil.join(", ")}`);
console.log(`Dieksekusi oleh V8 versi ${process.versions.v8}`);

Output yang Dihasilkan:

text
Hasil map: 2, 4, 6, 8, 10
Dieksekusi oleh V8 versi 13.6.233.17-node.53

Mari kita telaah baris-baris kode di atas:

  1. Baris 1-9 (class Bilangan): definisi class dengan satu property nilai dan satu method ganda(). Semua instance yang dibuat dari class ini memiliki bentuk yang sama, dan V8 memanfaatkan kesamaan bentuk tersebut untuk mengoptimasi akses property.
  2. Baris 11 (map dengan arrow function): method map memanggil new Bilangan(n).ganda() untuk tiap elemen array. V8 mengeksekusi callback ini berulang kali, sehingga callback menjadi kandidat optimasi JIT.
  3. Baris 13-14 (process.versions.v8): object process menyediakan informasi runtime; property versions.v8 menampilkan versi V8 yang tertanam pada Node.js yang sedang berjalan.

Pola Object yang Stabil Membantu Optimasi #

Salah satu konsekuensi praktis dari arsitektur V8: bentuk object yang konsisten membantu optimasi, sedangkan bentuk yang berubah-ubah memicu deoptimisasi. V8 mengelompokkan object dengan susunan property yang sama ke dalam struktur internal yang seragam; ketika kita menambah property di tengah jalan atau mengganti-ganti tipe nilai, kelompok tersebut pecah dan hasil optimasi sebelumnya dibuang.

js Pola akses property yang stabil
function totalHarga(harga) {
  return harga.awal - harga.diskon;
}

// Semua argument punya bentuk identik: awal lalu diskon.
const promoMinggu = { awal: 150000, diskon: 25000 };
const promoBulan = { awal: 300000, diskon: 50000 };

console.log(totalHarga(promoMinggu) + totalHarga(promoBulan));

Versi V8 di Dalam Node.js #

Setiap versi major Node.js menautkan satu versi V8 tertentu — pada Node.js 24 yang dipakai Course ini, V8 berada di versi 13.6, sebagaimana tercetak pada output demo di atas. Konsekuensinya penting untuk kita pahami: fitur bahasa JavaScript baru tersedia di Node.js hanya setelah versi V8 yang membawanya ikut tertanam, dan pembaruan besar itu terjadi pada garis rilis major baru. Untuk memeriksa versi ini di komputer mana pun, kita cukup membaca process.versions.v8 atau modul node:v8 yang juga menyediakan alat bantu seperti statistik memori heap — keduanya terdokumentasi di API node:v8 dan API process .

V8 mengurus satu hal besar: mengeksekusi JavaScript dengan cepat. Pertanyaan berikutnya pun muncul — siapa yang membaca berkas app.mjs dari disk, menjadwalkan timer, dan menangani ratusan koneksi jaringan sekaligus? Jawabannya ada pada kerja sama V8 dengan libuv dan event loop, topik yang kita bedah pada Chapter Bagaimana Node.js Bekerja.