VUE
Optimize Component Re-renders with v-memo in Vue 3
Boost Vue 3 application performance by leveraging the `v-memo` directive to intelligently skip re-rendering static or conditionally changing parts of your templates.
<!-- MyOptimizedComponent.vue -->
<template>
<div>
<h1>v-memo Performance Optimization</h1>
<p>Current Time: {{ currentTime }}</p>
<!-- This block will only re-render if `memoCondition` changes -->
<div v-memo="[memoCondition]">
<h2>Memoized Section</h2>
<p>This content is expensive to compute or static.</p>
<p>Memo Condition: {{ memoCondition }}</p>
<p>Random Number (memoized): {{ Math.random() }}</p>
<button @click="incrementCounter">Increment Counter (inside memo)</button>
<p>Counter (inside memo): {{ internalCounter }}</p>
</div>
<hr />
<!-- This block will re-render normally -->
<p>Normal Section</p>
<p>Counter (normal): {{ normalCounter }}</p>
<button @click="normalCounter++">Increment Normal Counter</button>
<hr />
<!-- v-memo with an empty dependency array acts like v-once -->
<div v-memo="[]">
<h3>Truly Static Content (v-memo=[])</h3>
<p>This will only render once. {{ new Date().toLocaleTimeString() }}</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
const currentTime = ref(new Date().toLocaleTimeString())
const memoCondition = ref(0)
const internalCounter = ref(0)
const normalCounter = ref(0)
let timer: ReturnType<typeof setInterval>
onMounted(() => {
timer = setInterval(() => {
currentTime.value = new Date().toLocaleTimeString()
// Change memoCondition periodically to see the memoized block update
if (Math.random() < 0.1) { // 10% chance to change condition
memoCondition.value = Math.floor(Math.random() * 10)
}
}, 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
const incrementCounter = () => {
internalCounter.value++
}
</script>
How it works: The `v-memo` directive in Vue 3 provides a performance optimization similar to `useMemo` in React, allowing you to conditionally skip re-rendering parts of your template. You pass an array of dependencies to `v-memo`; the enclosed content will only re-render if any of these dependencies change. If the dependency array is empty (`v-memo="[]"`), the element and its children will only render once, behaving like `v-once`. This is particularly useful for static content or complex sub-trees whose data rarely updates, preventing unnecessary DOM updates and improving application responsiveness.