Optimasi Performa Vue dengan Key, Lazy Rendering, dan Watch Effect

Ketika aplikasi Vue mulai tumbuh dan memiliki banyak komponen, masalah performa bisa muncul tanpa disadari, tampilan terasa lambat, re-render yang tidak perlu, atau proses komputasi yang berat terus berjalan di background. Vue sebenarnya sudah sangat efisien secara default, tetapi ada beberapa fitur dan teknik penting yang dapat membantu kita menjaga performa aplikasi tetap optimal, terutama dalam proyek skala menengah hingga besar.
Dalam artikel ini, kita akan membahas tiga konsep penting yang sering menjadi kunci dalam optimasi performa Vue:
- Penggunaan atribut
key
untuk efisiensi render list - Teknik Lazy Rendering (Penundaan Render) agar UI tidak membebani DOM
- Pemanfaatan
watchEffect
untuk reaktivitas yang efisien dan selektif
1. Pentingnya key
untuk Optimasi Rendering
Vue menggunakan Virtual DOM untuk memperbarui tampilan dengan efisien. Namun, ketika kita menampilkan daftar elemen menggunakan v-for
, Vue perlu tahu bagaimana membedakan setiap item dalam daftar. Di sinilah atribut key
berperan.
Tanpa key
, Vue akan mencoba memperbarui elemen DOM secara “cerdas” berdasarkan posisi — tapi kadang hasilnya tidak sesuai harapan. Misalnya, ketika item dihapus atau ditambahkan di tengah daftar, Vue bisa saja mengubah isi elemen lama alih-alih membuat ulang elemen baru. Ini bisa menimbulkan bug tampilan.
Contoh Tanpa key
<template>
<ul>
<li v-for="item in items">{{ item.name }}</li>
</ul>
</template>
<script setup>
const items = [
{ id: 1, name: 'A' },
{ id: 2, name: 'B' },
{ id: 3, name: 'C' }
]
</script>
Jika item dihapus atau urutan berubah, Vue mungkin “menukar” elemen tanpa benar-benar merender ulang.
Contoh Dengan key
yang Benar
<template>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</template>
Dengan :key
, Vue tahu persis elemen mana yang berubah, sehingga hanya bagian yang perlu diperbarui yang akan di-render ulang.
Tips Praktis:
- Gunakan nilai unik dan stabil, seperti
id
database. - Jangan gunakan index array (
:key="index"
) kecuali list benar-benar statis. - Penggunaan
key
yang konsisten mencegah re-render penuh dan meningkatkan kinerja UI besar seperti tabel dinamis atau daftar panjang.
2. Lazy Rendering: Render Hanya Saat Diperlukan
Lazy Rendering atau penundaan render berarti kita hanya menampilkan elemen saat benar-benar dibutuhkan.
Konsep ini sangat penting untuk halaman yang panjang, daftar komponen besar, atau tampilan dengan banyak tab.
Kasus Umum Tanpa Lazy Rendering
Bayangkan kita memiliki tiga tab besar dalam satu halaman, masing-masing dengan 20 komponen di dalamnya. Jika kita menulis:
<template>
<div>
<TabA />
<TabB />
<TabC />
</div>
</template>
Semua tab akan di-render sekaligus walaupun hanya satu yang ditampilkan. Ini jelas membuang sumber daya.
Menggunakan v-if
untuk Lazy Render
<template>
<div>
<button @click="active = 'A'">Tab A</button>
<button @click="active = 'B'">Tab B</button>
<button @click="active = 'C'">Tab C</button>
<TabA v-if="active === 'A'" />
<TabB v-if="active === 'B'" />
<TabC v-if="active === 'C'" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import TabA from './TabA.vue'
import TabB from './TabB.vue'
import TabC from './TabC.vue'
const active = ref('A')
</script>
Dengan v-if
, hanya tab yang aktif saja yang dirender.
Ketika pengguna berpindah tab, Vue akan membuang komponen lama dari DOM dan membuat ulang yang baru.
Namun, jika kita ingin menyimpan state komponen (misalnya form tetap terisi ketika kembali ke tab sebelumnya), gunakan v-show
atau kombinasi dengan <keep-alive>
.
Kombinasi v-show
dan <keep-alive>
<template>
<keep-alive>
<TabA v-show="active === 'A'" />
<TabB v-show="active === 'B'" />
<TabC v-show="active === 'C'" />
</keep-alive>
</template>
Dengan pendekatan ini:
v-show
hanya menyembunyikan komponen tanpa menghapusnya dari DOM.<keep-alive>
memastikan state komponen tetap tersimpan, misalnya input atau scroll position.
Kesimpulan:
Gunakan v-if
untuk komponen berat yang jarang digunakan, dan v-show
dengan keep-alive
untuk tampilan yang sering berpindah tetapi ingin mempertahankan state.
3. Optimasi Reaktivitas dengan watchEffect
Vue memiliki sistem reaktivitas yang pintar — ia akan secara otomatis memperbarui komponen saat data berubah. Tapi jika tidak hati-hati, kita bisa memicu re-render yang tidak perlu, terutama jika ada banyak watch
atau computed
kompleks.
Di Vue 3, watchEffect()
memberikan kontrol yang lebih efisien atas apa yang perlu “dipantau” secara reaktif.
Cara Kerja watchEffect
watchEffect
menjalankan fungsi dan otomatis melacak dependensi reaktif yang digunakan di dalamnya.
Setiap kali salah satu dependensi berubah, fungsi itu akan dijalankan ulang.
<script setup>
import { ref, watchEffect } from 'vue'
const count = ref(0)
const doubled = ref(0)
watchEffect(() => {
doubled.value = count.value * 2
})
</script>
Setiap kali count
berubah, Vue akan menjalankan kembali fungsi di dalam watchEffect
.
Perbedaan watch
dan watchEffect
Fitur | watch | watchEffect |
---|---|---|
Mengamati variabel tertentu | Ya, spesifik | Tidak, otomatis berdasarkan penggunaan |
Akses nilai lama & baru | Ya | Tidak |
Waktu inisialisasi | Tidak langsung jalan | Langsung dijalankan sekali |
Penggunaan umum | Reaksi terhadap data tertentu | Efek samping otomatis (misalnya update UI, sync data) |
Contoh Optimasi dengan watchEffect
Misalnya kita ingin memantau filter pencarian tanpa harus men-trigger request setiap kali pengguna mengetik satu huruf.
Kita bisa mengombinasikan watchEffect
dengan setTimeout
untuk debounce:
<script setup>
import { ref, watchEffect } from 'vue'
const search = ref('')
const results = ref([])
watchEffect(() => {
const timeout = setTimeout(() => {
if (search.value.trim() !== '') {
console.log('Fetching data for:', search.value)
// Lakukan request API di sini
}
}, 500)
return () => clearTimeout(timeout) // cleanup
})
</script>
<template>
<input v-model="search" placeholder="Cari produk..." />
</template>
Dengan pendekatan ini, API hanya dipanggil setelah 500ms pengguna berhenti mengetik — menghemat sumber daya dan mempercepat respons UI.
4. Kombinasi Ketiganya dalam Skenario Nyata
Misalkan kita membuat aplikasi daftar produk e-commerce dengan ribuan item. Kita bisa menggabungkan ketiga teknik di atas:
- Gunakan
:key
div-for
agar list efisien saat data berubah. - Terapkan Lazy Rendering untuk tab atau filter berat seperti kategori dan rekomendasi.
- Gunakan
watchEffect
untuk memantau filter pencarian dan update data dengan optimal.
Contoh Sederhana
<template>
<div>
<input v-model="search" placeholder="Cari produk..." />
<div v-if="filteredProducts.length === 0">
Tidak ada hasil.
</div>
<ul>
<li v-for="product in filteredProducts" :key="product.id">
{{ product.name }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref, computed, watchEffect } from 'vue'
const products = ref([
{ id: 1, name: 'Laptop' },
{ id: 2, name: 'Keyboard' },
{ id: 3, name: 'Mouse' },
{ id: 4, name: 'Monitor' },
])
const search = ref('')
const filteredProducts = ref([])
watchEffect(() => {
filteredProducts.value = products.value.filter(p =>
p.name.toLowerCase().includes(search.value.toLowerCase())
)
})
</script>
Vue hanya akan memperbarui list yang relevan — cepat, efisien, dan mudah dipahami.
5. Tips Tambahan untuk Optimasi Performa
- Gunakan
v-once
untuk elemen statis yang tidak berubah. - Manfaatkan
computed
untuk perhitungan berat, bukan di template langsung. - Hindari loop bersarang dan gunakan pagination jika list terlalu panjang.
- Gunakan dynamic import atau code-splitting dengan
defineAsyncComponent
untuk komponen besar yang jarang digunakan.
Optimasi performa di Vue tidak selalu berarti menulis kode yang rumit — cukup memahami bagaimana Vue bekerja dan memanfaatkan fitur yang sudah disediakan dengan tepat.
key
membantu Vue membedakan dan memperbarui elemen DOM dengan efisien.- Lazy Rendering memastikan hanya bagian yang dibutuhkan yang dirender, menghemat sumber daya.
watchEffect
memberi kita kontrol penuh terhadap kapan dan bagaimana efek reaktif dijalankan.
Dengan menggabungkan ketiganya, aplikasi Vue akan terasa lebih ringan, responsif, dan tetap mudah dipelihara seiring bertambahnya kompleksitas.