Reputation: 3642
Am trying to improve the performance of my vuejs app, and I cant figure out why some components are re-rendering...
According to the hook's lifecycle, a component should re-render
when data changes
Looking here and there I assume this means a change to either $props
or $data
, but I must be wrong because often neither of them are modified but still the beforeUpdate
and updated
hooks are triggered meaning it is indeed re-rendered. So when is a component re-rendered?
EDIT: how do I see that neither $props
nor $data
are modified? I set a deep watcher on each of them, and these watchers are not triggered
EDIT 2: in addition to $props
and $data
, a change to any slots would also cause a re-render. This explain some cases but still, I have some components without any slots for which the updated
hook is triggered without $props
or $data
being changed
EDIT 3: apparently if a component has a prop that is an object and some other part of this object is modified, it may trigger an update of the component... still trying to find some confirmation on this
Upvotes: 4
Views: 7184
Reputation: 4801
Let's first talk about updates to the DOM.
In general, each data property in Vue instance has its own watcher
.
You can narrow it down to 3 layers:
Vue instance watches the Virtual DOM.
Virtual DOM is a representation of the real DOM but parsed in JS
(much faster than the "real" DOM).
Then when we modify some property, Vue instance re-creates the "New" Virtual DOM (The "Template") and checks for differences between the "Old" Virtual DOM. If it is different then it only updates that particular part in "real" DOM.
beforeUpdate()
and updated()
hooks.
Once mounted()
there is an ongoing lifecycle, that is whenever the data changes that require the DOM to update, both hooks are triggered - beforeUpdate()
and update()
.
Note: beforeUpdate()
and update()
are not executed if the DOM was has not been changed - even if you trigger an event.
Have a look below at the example you can see that beforeUpdate()
and update()
hooks are executed only the first time after pressing the button. Every next time, the click
is triggered but the DOM is not changed, thus the hooks are not triggered.
new Vue({
el: '#app',
data: {
title: 'Vue instance'
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('update')
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>{{title}}</h1>
<button @click="title='changed'">Update</button>
</div>
Conclusion:
Based on the above, we can see that beforeUpdate()
and updated()
hooks are called when the "real" DOM is updated > which is caused by changes in Virtual DOM > which is caused by changes in Vue instance that reflects the changes to the Virtual DOM.
So in other words the component will re-render when any reactive dependency of the template changes.
This includes: props
, data
, and computed
properties.
Upvotes: 6