Vue Tips: Optimize your Vue Apps with v-once and v-memo
Tags: vue, webdev, javascript
Published: 2022-09-04 12:14:06

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](https://fjolt.com/article/vue-tips-dynamic-styles). 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:
```html
<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>
```

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:
```html
<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>
```

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:
```html
<h1 v-memo="[ message, question ]"></h1>
```

It's also interesting to note that passing in an empty array makes `v-memo` work the same as `v-once` 😄:
 ```html
<h1 v-memo="[]"></h1>
```

## 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](https://fjolt.com/category/vue).