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>
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>
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>
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>
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.