vue-hot-reload-api
vue-hot-reload-api copied to clipboard
Hot reload and memory leak (functional components)
Version:
v2.3.4
How to reproduce:
Just comand+c & comand-v in your terminal: (ctrl+c & ctrl+v / copy & past)
vue create -d -n vue-memory-leak-functional;
cd vue-memory-leak-functional;
yarn;
# create Functional.vue
echo "<script>
export default {
name: 'Functional',
functional: true,
render(createElement) {
return createElement('div', 'HelloWorld');
}
}
</script>" > src/components/Functional.vue
# create JustComponent.vue
echo "<template>
<div>
<functional v-for=\"i in 100\" :key=\"i\" />
</div>
</template>
<script>
import Functional from \"./Functional\";
export default {
name: 'JustComponent',
components: { Functional },
}
</script>" > src/components/JustComponent.vue
# update HelloWorld.vue
echo "<template>
<div>
<just-component v-if=\"show\" />
</div>
</template>
<script>
import JustComponent from \"./JustComponent\";
export default {
name: 'HelloWorld',
components: {JustComponent},
data() {
return {
show: true
}
},
created() {
setInterval(()=>{
this.show = \!this.show;
}, 1000);
},
}
</script>" > src/components/HelloWorld.vue
yarn serve;
after that open devtool > more tools > performance monitor

Or, manual:
vue create -d -n vue-memory-leak-functional;
cd vue-memory-leak-functional;
yarn;
Update HelloWorld.vue
<template>
<div>
<just-component v-if="show" />
</div>
</template>
<script>
import JustComponent from "./JustComponent";
export default {
name: 'HelloWorld',
components: {JustComponent},
data() {
return {
show: true
}
},
created() {
setInterval(()=>{
this.show = !this.show;
}, 1000);
},
}
</script>
Functional.vue
<script>
export default {
name: 'Functional',
functional: true,
render(createElement) {
return createElement('div', 'HelloWorld');
}
}
</script>
JustComponent.vue
<template>
<div>
<functional v-for="i in 100" :key="i" />
</div>
</template>
<script>
import Functional from "./Functional";
export default {
name: 'JustComponent',
components: { Functional },
}
</script>
After that just start
yarn serve;
I can confirm this is still an issue in 2.6.10 on my end. I'm testing this with an empty functional component:
<template functional>
</template>
toggling v-if on a parent where this component is nested into will cause a detached HTMLDivElement in the memory heap. I got the suspicion that this causes further memory issues. As soon as I remove functional from the template tag this leak is gone.
In conclusion, functional components cannot be used in Vue 2, I will convert all my functional components to normal components to bypass this issue.
@martin-braun this only affects the hot reload mode. Yes it can mess up development because memory increases, and you can't really debug memory leaks, but in a production build, the functional components are cleaned up correctly.