Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak on unmounted DOM element or component #11318

Closed
JochemBruijninckx opened this issue Jul 8, 2024 · 4 comments
Closed

Memory leak on unmounted DOM element or component #11318

JochemBruijninckx opened this issue Jul 8, 2024 · 4 comments

Comments

@JochemBruijninckx
Copy link

JochemBruijninckx commented Jul 8, 2024

Vue version

3.4.29

Link to minimal reproduction

Reproduction

Steps to reproduce

Click the toggle button a few times.

What is expected?

There is a div with an @click event listener, and my expectation is that the event listener should be added when the div is mounted to the DOM and removed when the div is unmounted.

What is actually happening?

The console shows that the event listener gets added, but never that it gets removed. Performance recordings show that the amount of listeners keeps increasing, never decreasing.
Screenshot 2024-07-08 163538

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i5-12400F
    Memory: 3.23 GB / 15.79 GB
  Binaries:
    Node: 18.17.1 - C:\Program Files\nodejs\node.EXE
    npm: 10.1.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (126.0.2592.87)
    Internet Explorer: 11.0.22621.3527
  npmPackages:
    vue: ^3.4.29 => 3.4.31

Any additional comments?

Using vue in the building of an online game where elements with click/mouseenter/mouseleave events often are added/removed from the DOM, and noticed significant memory leaks with ever-increasing listener amounts.

Thanks in advance for any help!

@edison1105
Copy link
Member

EventTarget.prototype.addEventListener = function (type, listener, options) {
-  console.log(`Added event listener: ${type}`, this);
  originalAddEventListener.call(this, type, listener, options);
};

EventTarget.prototype.removeEventListener = function (type, listener, options) {
-  console.log(`Removed event listener: ${type}`, this);
  originalRemoveEventListener.call(this, type, listener, options);
};

console.log() causes memory leaks

@JochemBruijninckx
Copy link
Author

EventTarget.prototype.addEventListener = function (type, listener, options) {
-  console.log(`Added event listener: ${type}`, this);
  originalAddEventListener.call(this, type, listener, options);
};

EventTarget.prototype.removeEventListener = function (type, listener, options) {
-  console.log(`Removed event listener: ${type}`, this);
  originalRemoveEventListener.call(this, type, listener, options);
};

console.log() causes memory leaks

Thanks, that makes sense! Still, regardless of the memory leaks it does seem strange to me that the removal of the listener is logged when removing it manually but not when the div is unmounted. Or is that expected behaviour?

@LinusBorg
Copy link
Member

LinusBorg commented Jul 9, 2024

That's because the elements are removed from the DOM when the component is unmounted, so they will be garbage collected and so there's no need to remove the listeners. Removing them individually would just be overhead

@JochemBruijninckx
Copy link
Author

That's because the elements are removes from the DOM when the component is unmounted, so they will be garbage collected and so there's no need to remove the listeners. Removing them individually would just be overhead

Thanks a lot, that's a clear explanation and cool to hear how that works! Then I'll have to search elsewhere for what's causing my leak 😄

@github-actions github-actions bot locked and limited conversation to collaborators Jul 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
3 participants