I've written a component using the defineComponent
syntax, with a template, like this:
<script>
import MySvgComponent from './MySvgComponent.vue'
const MyComponent = defineComponent({
components: {
MySvgComponent
},
template: `
<div><MySvgComponent /></div>
`,
})
</script>
For some reason, when I do this, I get the following warning:
"Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with markRaw
or using shallowRef
instead of ref
"
The solution here is to wrap the imported component in either markRaw or shallowRef, which resolves the warning, like this:
<script>
import { markRaw } from 'vue'
import MySvgComponent from './MySvgComponent.vue'
const MyRawSvgComponent = markRaw(MySvgComponent);
const MyComponent = defineComponent({
components: {
MyRawSvgComponent
},
template: `
<div><MyRawSvgComponent /></div>
`,
})
</script>
Why does this resolve the warning?
It looks like based on the documentation that wrapping a Javascript object in markRaw
returns a non-proxied version of the original object. Why do we need to do that here, and what exactly is the performance issue going on here that we're resolving by using the markRaw
or shallowRef
functions?
It is all explained in the documentation.
The problem is that
Component instances are much more expensive than plain DOM nodes, and creating too many of them due to abstraction patterns will incur performance costs.
Read More
In addition, Vue's reactivity system is deep by default. While this makes state management intuitive, it does create a certain level of overhead when the data size is large, because every property access triggers proxy traps that perform dependency tracking. This typically becomes noticeable when dealing with large arrays of deeply nested objects, where a single render needs to access 100,000+ properties, so it should only affect very specific use cases.
Read More
To avoid these issues Vue component instances/objects without the shallowRef or markRaw() needs to be flagged, this is to ensure optimisation and performance.
shallowRef
is typically used for performance optimizations of large data structures, or integration with external state management systems.
Read More about Shallow Ref
markRaw()
on the other hand marks an object so that it will never be converted to a proxy. Returns the object itself.
Read More about markRaw()