Vue Tips: Optimize your Vue Apps with v-once and v-memo

Johnny Simpson - Sep 4 '22 - - Dev Community

Vue is like any other tool we use on the web - your mileage will vary depending on how you use it. If you write poorly optimised code, you'll still get a slow website, even if Vue has lots of tricks to try and improve performance. As such, today we'll be looking at how we can optimise performance using two little known Vue HTML attributes known as v-once and v-memo. Both of these allow us to optimise when a component or component tree is re-rendered.

These two attributes are not actually used very regularly, but they can be super useful in a whole set of different circumstances. In this guide, I hope I'll be able to give you an understanding of what each does, so that you can use them on your next Vue project.

v-once in Vue

When a reactive element updates, Vue will update your DOM and any CSS Vue variables accordingly. However, if you know something should only ever be rendered once, you can tell Vue directly so that it will never update that portion of the DOM tree. To do that, we use the magical attribute, v-once. Let's look at an example, where I am using v-once on an <h1> tag:

<script setup>
import { ref } from 'vue'

let message = ref("Hello World")

let updateMessage = () => {
    message.value = 'Goodbye World'
}
</script>

<template>
    <h1 v-once>{{message}}</h1>
    <input :value="message" />
    <button @click="updateMessage">
        Update Message
    </button>
</template>
Enter fullscreen mode Exit fullscreen mode

Here, we have a reactive variable called message set to Hello World, which can be updated on the click of a button to Goodbye World. We are using this message variable in both our h1 header, and as the value of our input.

Although clicking the button will update the value of the input - the h1 will still have the old Hello World text, since it has the attribute v-once. Essentially, the h1 only gets rendered once and never updated again. This is super useful for using variables and having them update in some places, but not in others. It is also really helpful for optimising your code too! This also applies to any variable mentioned within <h1> or its sub-structure - the entire structure is only rendered once.

v-once can be used pretty much anywhere - including within v-for loops - making it universally useful in Vue.

v-memo

v-memo is kind of similar to v-once, but it gives us a little more flexibility. Within v-memo, we can define an array of variables which, should they update, we will re-render this element and any tags within it. This even applies to variables not mentioned within the HTML tag - so we can force a re-render using this method too.

The beauty of this is that if we have a situation where multiple variables will always update at the same time, we can avoid multiple re-renders. Let's look at a modified version of the code we used for v-once. Here, we have two variables now - message and question. Each update on the click of separate buttons - one for the question, and one for the message. I am using v-memo on the <h1> tag to only update it, should message update:

<script setup>
import { ref } from 'vue'

let message = ref("Hello World")
let question = ref("How are you?")

let updateMessage = () => {
  message.value = 'Goodbye World'
}
let updateQuestion = () => {
  question.value = 'What is your name?'
}
</script>

<template>
  <h1 v-memo="[ message ]">{{message}} - {{question}}</h1>
  <button @click="updateMessage">
    Update Message
  </button>
  <button @click="updateQuestion">
    Update Question
  </button>
</template>
Enter fullscreen mode Exit fullscreen mode

If we click ont the Update Question button, nothing will change for the user, since v-memo only watches for changes in message, not question - but the question variable will still be updated in the background. However, if we click on the Update Message button, then the <h1> will update immediately, as we have told v-memo to only update should that variable change.

This is a pretty neat trick for optimisation, but it also has other uses. For example, you could update an element and all elements/variables within it only when a certain condition is met in your code. The only thing to note is you cannot use v-memo in a v-for loop - so this is something to watch out for.

You can define multiple variables for v-memo by adding them to the array object within v-memo, like so:

<h1 v-memo="[ message, question ]"></h1>
Enter fullscreen mode Exit fullscreen mode

It's also interesting to note that passing in an empty array makes v-memo work the same as v-once 😄:

<h1 v-memo="[]"></h1>
Enter fullscreen mode Exit fullscreen mode

Conclusion

I hope you've enjoyed this vue tip, and overview of v-once and v-memo. Both of these attributes are super useful and I hope you'll find a way to use them in your next Vue project. For more Vue content, you can check out other articles I've written on my block here.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .