State management yang besar bisa menjadi sumber re-render berlebihan. Episode ini membahas cara mengontrol re-render dengan storeToRefs dan state granular, memakai $subscribe dengan opsi detached, serta membatch banyak update dengan $patch untuk performa yang lebih baik.

Semakin besar aplikasi, semakin mudah store menjadi sumber re-render yang tidak perlu. Setiap field state yang berubah bisa memicu ulang komponen yang membacanya — dan jika seluruh komponen membaca seluruh store, satu perubahan kecil berujung render massal.
Episode 13 membahas tuning reactivity Pinia: mengontrol re-render dengan storeToRefs dan akses granular, memakai $subscribe dengan opsi detached, serta membatch update dengan $patch. Ini bukan mikro-optimasi — ini pola yang mencegah aplikasi melambat saat store tumbuh.
Perhatikan bagaimana cara membaca memengaruhi re-render:
// Re-render saat field yang dipakai berubah
const { count, double } = storeToRefs(store)
// Potensi re-render lebih luas: template membaca banyak properti
const store = useCounterStore()const { count, double } = storeToRefs(store) mengambil hanya field yang dibutuhkan, sehingga Vue hanya melacak dependency itu. Sebaliknya, memakai store utuh dan membaca banyak properti bisa menciptakan lebih banyak dependency — tidak salah, tetapi kurang presisi.
Jangan menaruh seluruh data aplikasi di satu store besar. Pecah menjadi store kecil dan state yang spesifik:
// Buruk: satu state menampung banyak domain
state: () => ({ user: {}, cart: [], ui: { modal: null } })
// Lebih baik: terpisah per store
useAuthStore() // user
useCartStore() // cart
useUiStore() // modal, sidebarDengan store terpisah, komponen yang hanya butuh cart tidak ikut terpengaruh saat ui berubah. Prinsip ini mengurangi re-render dan membuat dependency tracking lebih tajam.
Secara default, $subscribe berhenti saat komponen yang mendaftarkannya dibongkar. Untuk subscriber yang hidup lebih lama, kirim { detached: true }:
store.$subscribe(
(_mutation, state) => {
saveToStorage(state)
},
{ detached: true },
){ detached: true } membuat subscriber tetap aktif meskipun komponen sudah di-unmount. Gunakan untuk tugas jangka panjang seperti autosave. Jika tidak, biarkan default agar subscriber ikut dibersihkan dan tidak bocor.
Beberapa assignment berurutan memicu banyak pembaruan. $patch menggabungkannya menjadi satu:
// Tiga pembaruan terpisah
store.firstName = 'Arman'
store.lastName = 'Dwi'
store.age = 26
// Satu patch
store.$patch({
firstName: 'Arman',
lastName: 'Dwi',
age: 26,
})store.$patch({ ... }) mengelompokkan perubahan sehingga subscriber dan DevTools hanya mencatat satu mutasi. Ini penting untuk sinkronisasi storage dan observability yang lebih efisien.
Pinia menyediakan dua jalan untuk memantau perubahan: $subscribe milik store dan watch milik Vue. Kapan memakai yang mana?
$subscribe hanya mendeteksi perubahan state setelah sukses dimutasi, dan { flush: 'sync' } bisa diatur agar callback berjalan sebelum komponen re-render. Cocok untuk sinkronisasi eksternal seperti storage atau analytics.watch(store.$state, ...) memakai mekanisme watch Vue biasa, mendukung deep dan immediate, serta lebih mudah dibatalkan jika sumbernya adalah composable milik kalian sendiri.watch(
() => store.$state.cart,
(cart) => {
console.log('cart berubah', cart)
},
{ deep: true },
)Untuk kasus sederhana, pilih yang paling sedikit memakai API eksternal: watch bila kalian sudah di dalam komponen dan butuh dependency tracking standar, $subscribe bila kalian bekerja dengan store secara langsung, misalnya di plugin atau saat membuat utility yang hidup di luar komponen.
Warning
Optimasi tidak dimulai dari mikro-patch. Mulailah dari struktur data: store kecil per domain dan akses granular. $patch dan detached adalah penyempurnaan setelah fondasi sudah benar.
Episode 13 membekali kalian pola performance yang bisa langsung diterapkan. Kalian sekarang bisa mengontrol re-render dengan storeToRefs dan state granular, mengatur umur subscriber dengan detached, serta membatch update dengan $patch.
Inti yang harus dibawa pulang:
storeToRefs membatasi dependency tracking pada field yang dipakai.{ detached: true } membuat $subscribe hidup lebih lama.$patch menggabungkan banyak update menjadi satu mutasi.Di episode 14 selanjutnya kita akan membahas async server state dan integrasi lanjutan — Pinia Colada untuk fetching dan caching server state, menggabungkan store dengan Vue Router, serta integrasi dengan composables eksternal. Ini jembatan Pinia menuju arsitektur aplikasi modern.