Subscribe on changes!

Memory leak / component v-if ?

avatar
Jan 2nd 2023

Vue version

3.2.45

Link to minimal reproduction

https://sfc.vuejs.org/#eNqdVE2P2jAQ/StWVGlBgniXthcKiFba2/bW3nIJyWQ33cS2bCe7CPHf++wkEMKC0OYQzXjefHjmjXfBT6XCuqJgHixMonNlV5HISyW1ZX/izQPLtCxZFITcaQ4ZBT/6iNkJYjZE7JimbMKk+C0rYSll+w7fAendA1PK4qqAQyQYSyS8BQlr5s0B88VMDuLMi3v/N2QrNRp3wEQKY5l5kW++/qUrYGR1RWMkcwANvBYdHP4ttI2+9zAX2kkLfugKFEulKmJL0BhbpHntBYg+1VoqEq64ZRT08mdxYXBVVk/zrGfBCe+5z9h6Eyevp66ubO9JCNHCF7zJu+C9aqAauy2ImQRFpCuU7VRYgknQjGJaxir8Z6TAqP3do9ZgouDQ5XYscwgv1ioz57wS6vU5xET4GjauMca8pGkqy/XXcBZ++456jO2fh2TK6UbLN0MaGaOg7awPznFYk55qEilp0leTDbAnCQe2s6R+ihgiGtAR05H8fISwXuzpYCN2RyI7Tv+iTGr6K0p3dBuzG7IqLZWZIByVORwH3H2lbSrfBOY/ojFbro5UzTMchbCz5RKJHk0SK+Q6+LvPhRxFgSMTLC3nfSuO7GbHe4ywOf0UqUyqEpsXxmn6WEN4QrNJkEbMtjAMtKuxi7/vhEFTLkbXVMqaPpGg295ra9qsQhGLZ7dOiQEbPlyM7kn7mBftbuZCVdY9IojlZQSzW0VQLb07La6szHAxc1zoTWWtFFhc9ML5sVywh/v7e6DXSZH7Pf/iJ3XXPRp34yhYPeWCFrzxvr7t15iJYs/ZeI2PAwI2V25eTlEVxXG4F0jDuXcJ67ioKPS9GF2c3IHMzuWGR/e2ae7/A16gPXA=

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:

https://we.tl/t-yXD6l3kVxm

avatar
Jan 2nd 2023

Can you try replicating it with the devtools disabled, maybe in an private tab?

avatar
Jan 2nd 2023

I did and it does the same thing.

avatar
Jan 2nd 2023

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?

avatar
Jan 2nd 2023

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 CleanShot 2023-01-02 at 17 34 18

After a minute CleanShot 2023-01-02 at 17 34 10

avatar
Jan 2nd 2023

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.

avatar
Jan 2nd 2023

Actually my screenshot shows a lower Heap but I can also reproduce more listeners and more dom nodes with a higher heap.

avatar
Jan 2nd 2023

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. CleanShot 2023-01-02 at 19 55 55

-> After several refresh of the page, the heap is going nuts! CleanShot 2023-01-02 at 19 56 37

avatar
Jan 30th 2023

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 image

avatar
May 8th 2023

@weidehai Unless I'm missing something, there's a removeEventListener in a onBeforeUnmount hook

avatar
Jun 7th 2023

Another similar reproduction here with Vue 3.3.4 I've tested in private mode.

  1. Switch to 'SelectPage' tab and switch back to 'EmptyPage'
  2. 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