Elements used for the initial rendering of a `v-for` are immune to GC
Vue version
3.4.6
Link to minimal reproduction
https://github.com/peter-gy/vue3-v-for-memory-leak-repro
Steps to reproduce
Using MS Edge makes it easier to investigate the detached elements, so it is recommended to use it for reproduction. Learn more about how to use the Edge DevTools to investigate memory leaks here.
- Open the app in MS Edge
- Open the DevTools and navigate to the "Detached Elements" tab
- Refresh the element state and force an initial garbage collection by clicking the trash icon
- Set the counter to 0
- Refresh the element state and force a garbage collection by clicking the trash icon again
- See that the detached elements are still there
What is expected?
After the initial items are removed from the DOM, they are removed from memory too, they don't keep on lingering in memory as detached elements.
What is actually happening?
All of the nodes used to initially render the list remain in the memory as detached elements.
System Info
No response
Any additional comments?
Screencast:
[!IMPORTANT]
While on the right side in the screencast, you can readVue ^3.3.11
, the bug is present on the current latest version3.4.6
too. The SFC Playground links to a repro using3.4.6
.
The https://github.com/peter-gy/vue3-v-for-memory-leak-repro repository allows you to check side-by-side that this behavior was not present in Vue2. Our team noticed massive memory leaks in our e2e test suite as we have been working on migrating from Vue2 to Vue3.
I think you closed this issue too quickly, I can reproduce these detached nodes even when hoistStatic
is set to false
.
Do note the detached elements do not increase over time so it is not a memory leak (which implies the memory would keep growing indefinitely).
I tend to disagree @yyx990803. In my "large" application, the v-for
iterates on some dynamic user input elements. Because of these detached elements, the memory increases and increases indefinitely.
Do note the detached elements do not increase over time so it is not a memory leak (which implies the memory would keep growing indefinitely).
In our case this is exactly what we experience. We have an E2E test suite where thousands of scenarios are executed one after the other. The memory occupied by the non-garbage-collected elements keep accumulating, as we move between scenarios. This is caused by the fact that the whole test suite is executed without any browser reload. This leads to crashing the testing process with an out-of-memory error.
Then unfortunately, your demo isn't showing the actual culprit because the detached elements you see are retained by __vnode
properties which are only attached in development mode for devtools usage. You can verify this by running a production build of your reproduction and see that there won't be any detached nodes.
The leak is therefore caused by something else and needs a valid reproduction.
I tend to disagree @yyx990803. In my "large" application, the
v-for
iterates on some dynamic user input elements. Because of these detached elements, the memory increases and increases indefinitely.
I'm speaking specifically about this reproduction. If you have a memory leak case, please provide a reproduction. Even a full application could work.
Then unfortunately, your demo isn't showing the actual culprit because the detached elements you see are retained by
__vnode
properties which are only attached in development mode for devtools usage. You can verify this by running a production build of your reproduction and see that there won't be any detached nodes.The leak is therefore caused by something else and needs a valid reproduction.
Thank you for the clarification. I can confirm that the described problem is not present in a production build. After further investigation on our side, this might really be a duplicate of #5256. Thanks a lot for having this issue reopened and for discussing the details though.
Closing this one for now then - please open a new issue if you find out the root cause of your leak is still from Vue core.
Closing this one for now then - please open a new issue if you find out the root cause of your leak is still from Vue core.
We had multiple leak sources, but running the tests using a production build as per your suggestion and patching the leak in a Vuetify component (vuetifyjs/vuetify#19024) seem to have solved our issues.