Memory leak / component v-if ?
Vue version
3.2.45
Link to minimal reproduction
Steps to reproduce
- Create a new project
- Alternate 2 components with v-if
- Add an input and focus on the mounted hook on one of the components
- Toggle between components, force the GC in Chrome Devtools each time you switch components
What is expected?
- The components and listeners should be GC and the memory should go back to initial level
What is actually happening?
- The number of listeners and components keeps growing and the memory heap as well
System Info
No response
Any additional comments?
I've been scratching my head for days now. I have a similar issue in my app, and it looks like it doesn't happen if I don't add the focus to the field in the mounted hook.
Problem seems systematic on Vue SFC, and it also happens, although not as consistently, on my test app:
I compared two heap snapshots on the provided reproduction and can't really spot anything extraordinary. Would you be able to provide a bit more guidance on where and how you see the leaked components and listeners?
Sorry, I actually commented out the focus in the SFC. It's back on.
What I do is play around with the buttons/esc to go back and forth, and randomly force GC in the Chrome console.
This is what I start with, and end up with after playing for a minute:
Fresh state
After a minute
Not a major overhead but when you work with lots of lines and an app that stays in for a long time you end up with a large chunk of memory leaking.
Actually my screenshot shows a lower Heap but I can also reproduce more listeners and more dom nodes with a higher heap.
Here's another interesting bit. I was testing again in private mode, on VueSFC, and after clicking and fiddling around for a while, just refreshing the page is increasing the memory heap.
-> After going back and forth between components, way too many event listeners compared to what it's supposed to be, and it's not going down even after garbage collecting.
-> After several refresh of the page, the heap is going nuts!
because vue didn't removeEventlistener explicit(in modern browser,removeEventlistener will be call automatic after dom remove),the question you mentioned that event listeners not going down,I guess the reason is browser control it clear action at specific conditions(not exactly at remove dom),and after reach a certain amount, it will not be grow up(switch tab many times and watch the event listeners count change) if you want to explict immediately remove it,you can do it like that
Another similar reproduction here with Vue 3.3.4 I've tested in private mode.
- Switch to 'SelectPage' tab and switch back to 'EmptyPage'
- GC
The heap size/DOM nodes did not go back. But it worked as expected when I switched between EmptyPage and DivPage tabs. Maybe there's something to do with the native select/option tag?
Also can check out the video in this issue