[Medium] Vue3 Static Hoisting
1. Apa itu Static Hoisting di Vue 3?
Jelaskan static hoisting di Vue 3.
Di Vue 3, static hoisting adalah optimasi saat kompilasi.
Definisi
Selama kompilasi template, Vue menganalisis node mana yang sepenuhnya statis (tidak ada dependensi reaktif). Node statis tersebut diangkat menjadi konstanta tingkat modul dan dibuat sekali saja. Pada render ulang berikutnya, Vue menggunakannya kembali alih-alih membuat dan membandingkannya lagi.
Cara kerjanya
Compiler menganalisis AST template dan mengangkat subtree yang tidak pernah berubah. Hanya bagian dinamis yang diregenerasi saat pembaruan.
Contoh sebelum/sesudah
Template sebelum kompilasi:
<template>
<div>
<h1>Judul statis</h1>
<p>Konten statis</p>
<div>{{ dynamicContent }}</div>
</div>
</template>
JavaScript hasil kompilasi (disederhanakan):
// node statis diangkat sekali
const _hoisted_1 = /*#__PURE__*/ h('h1', null, 'Judul statis');
const _hoisted_2 = /*#__PURE__*/ h('p', null, 'Konten statis');
function render() {
return h('div', null, [
_hoisted_1, // digunakan ulang
_hoisted_2, // digunakan ulang
h('div', null, dynamicContent.value), // dinamis
]);
}
Manfaat
- Biaya pembuatan VNode lebih rendah
- Pekerjaan diff lebih sedikit
- Performa render lebih baik
- Optimasi otomatis (tidak perlu kode tambahan)
2. Cara Kerja Static Hoisting
Bagaimana static hoisting bekerja secara internal?
Alur compiler
- Mendeteksi binding dinamis
{{ }},v-bind,v-if,v-for, props dinamis, dll.
- Menandai node statis
- Node dan anak-anaknya statis -> kandidat hoisting
- Mengangkat node statis
- Memindahkan node/konstanta statis ke luar
render()
- Memindahkan node/konstanta statis ke luar
Contoh 1: subtree yang sepenuhnya statis
<template>
<div>
<h1>Judul</h1>
<p>Ini adalah teks statis</p>
<div>Blok statis</div>
</div>
</template>
Hasil kompilasi (disederhanakan):
const _hoisted_1 = h('h1', null, 'Judul');
const _hoisted_2 = h('p', null, 'Ini adalah teks statis');
const _hoisted_3 = h('div', null, 'Blok statis');
function render() {
return h('div', null, [_hoisted_1, _hoisted_2, _hoisted_3]);
}
Contoh 2: campuran statis dan dinamis
<template>
<div>
<h1>Judul statis</h1>
<p>{{ message }}</p>
<div class="static-class">Konten statis</div>
<span :class="dynamicClass">Konten dinamis</span>
</div>
</template>
Hasil kompilasi (disederhanakan):
const _hoisted_1 = h('h1', null, 'Judul statis');
const _hoisted_2 = { class: 'static-class' };
const _hoisted_3 = h('div', _hoisted_2, 'Konten statis');
function render() {
return h('div', null, [
_hoisted_1,
h('p', null, message.value),
_hoisted_3,
h('span', { class: dynamicClass.value }, 'Konten dinamis'),
]);
}
Contoh 3: hoisting props statis
<template>
<div>
<div class="container" id="main">Konten</div>
<button disabled>Tombol</button>
</div>
</template>
Hasil kompilasi (disederhanakan):
const _hoisted_1 = { class: 'container', id: 'main' };
const _hoisted_2 = { disabled: true };
const _hoisted_3 = h('div', _hoisted_1, 'Konten');
const _hoisted_4 = h('button', _hoisted_2, 'Tombol');
3. Direktif v-once
Direktif
v-once
Jika developer ingin secara eksplisit menandai subtree sebagai render-sekali, gunakan v-once.
Apa yang dilakukan v-once
v-once memberitahu Vue untuk merender elemen/subtree ini sekali saja.
Meskipun ekspresi bersifat dinamis, mereka hanya dievaluasi pada render pertama dan tidak pernah diperbarui lagi.
Penggunaan dasar
<template>
<div>
<!-- render sekali -->
<div v-once>
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
<!-- area reaktif normal -->
<div>
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const title = ref('Judul awal');
const content = ref('Konten awal');
setTimeout(() => {
title.value = 'Judul baru';
content.value = 'Konten baru';
}, 1000);
</script>
v-once vs static hoisting
| Fitur | Static Hoisting | v-once |
|---|---|---|
| Pemicu | Analisis compiler otomatis | Direktif manual |
| Cocok untuk | Node yang sepenuhnya statis | Ekspresi dinamis yang seharusnya render sekali |
| Performa | Terbaik untuk bagian statis | Baik untuk render dinamis satu kali |
| Waktu keputusan | Saat kompilasi | Niat developer |
Kasus penggunaan umum
<template>
<!-- Kasus 1: data tampilan satu kali -->
<div v-once>
<p>Dibuat pada: {{ createdAt }}</p>
<p>Dibuat oleh: {{ creator }}</p>
</div>
<!-- Kasus 2: subtree berat tapi stabil -->
<div v-once>
<div class="header">
<h1>Judul</h1>
<nav>Navigasi</nav>
</div>
</div>
<!-- Kasus 3: snapshot satu kali di item list -->
<div v-for="item in items" :key="item.id">
<div v-once>
<h2>{{ item.title }}</h2>
<p>{{ item.description }}</p>
</div>
</div>
</template>
4. Pertanyaan Wawancara Umum
Pertanyaan wawancara umum
Pertanyaan 1: cara kerja internal static hoisting
Jelaskan static hoisting dan bagaimana ia meningkatkan performa.
Klik untuk melihat jawaban
Static hoisting adalah optimasi saat kompilasi:
- compiler memindai template untuk node statis vs dinamis
- node statis dipindahkan ke luar
render()sebagai konstanta - fase pembaruan menggunakan ulang node yang diangkat dan melewati pekerjaan diff-nya
Peningkatan performa datang dari:
- lebih sedikit alokasi VNode
- lebih sedikit traversal patch/diff
- lebih sedikit pembuatan objek berulang
Pertanyaan 2: static hoisting vs v-once
Jelaskan perbedaan dan kasus penggunaan.
Klik untuk melihat jawaban
- Static hoisting: otomatis, untuk segmen template yang sepenuhnya statis
v-once: manual, untuk ekspresi dinamis yang seharusnya tidak pernah diperbarui setelah render pertama
Gunakan static hoisting secara default (otomatis).
Gunakan v-once hanya ketika Anda sengaja menginginkan perilaku render-pertama-saja.
Pertanyaan 3: kapan peningkatan performa terlihat
Dalam skenario apa static hoisting paling efektif?
Klik untuk melihat jawaban
Paling terlihat ketika:
- Component mengandung banyak markup statis
- Component sering diperbarui tetapi hanya sebagian kecil yang dinamis
- Banyak instance berbagi struktur statis serupa
Semakin tinggi rasio statis-terhadap-dinamis dan frekuensi pembaruan, semakin besar keuntungannya.
5. Praktik Terbaik
Praktik terbaik
Disarankan
<!-- 1) Biarkan compiler mengangkat konten statis secara otomatis -->
<template>
<div>
<h1>Judul</h1>
<p>Konten statis</p>
<div>{{ dynamicContent }}</div>
</div>
</template>
<!-- 2) Gunakan v-once hanya untuk rendering satu kali yang disengaja -->
<template>
<div v-once>
<p>Dibuat pada: {{ createdAt }}</p>
<p>Dibuat oleh: {{ creator }}</p>
</div>
</template>
<!-- 3) Pisahkan layout stabil dari area dinamis jika memungkinkan -->
<template>
<div class="container">
<header>Header statis</header>
<main>{{ content }}</main>
</div>
</template>
Hindari
<!-- 1) Jangan gunakan v-once pada konten yang harus diperbarui -->
<template>
<div v-once>
<p>{{ shouldUpdateContent }}</p>
</div>
</template>
<!-- 2) Jangan blindly menerapkan v-once pada node list dinamis -->
<template>
<div v-for="item in items" :key="item.id" v-once>
<p>{{ item.content }}</p>
</div>
</template>
6. Ringkasan Wawancara
Ringkasan wawancara
Ingatan cepat
Static hoisting:
- optimasi otomatis saat kompilasi
- mengangkat node/konstanta statis
- mengurangi biaya pembuatan VNode dan diff
v-once:
- perilaku render-sekali yang dikontrol developer
- dapat menyertakan ekspresi dinamis
- tidak ada pembaruan setelah render pertama
Contoh jawaban
T: Apa itu static hoisting di Vue 3?
Ini adalah optimasi compiler di mana node template yang sepenuhnya statis diangkat keluar dari fungsi render menjadi konstanta. Mereka dibuat sekali dan digunakan ulang di seluruh pembaruan, mengurangi overhead pembuatan VNode dan diff.
T: Apa bedanya dengan v-once?
Static hoisting bersifat otomatis dan berlaku untuk konten yang sepenuhnya statis.
v-oncebersifat manual dan dapat menyertakan ekspresi dinamis, tetapi blok tersebut hanya dirender sekali dan tidak pernah diperbarui setelahnya.