Subscribe on changes!

Elements used for the initial rendering of a `v-for` are immune to GC

avatar
Jan 9th 2024

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.

  1. Open the app in MS Edge
  2. Open the DevTools and navigate to the "Detached Elements" tab
  3. Refresh the element state and force an initial garbage collection by clicking the trash icon
  4. Set the counter to 0
  5. Refresh the element state and force a garbage collection by clicking the trash icon again
  6. 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?

Vue SFC Playground Repro Link

Screencast:

[!IMPORTANT]
While on the right side in the screencast, you can read Vue ^3.3.11, the bug is present on the current latest version 3.4.6 too. The SFC Playground links to a repro using 3.4.6.

https://github.com/peter-gy/vue3-v-for-memory-leak-repro/assets/40776291/0dfc6b7e-56e3-4266-8737-aeee32cf4945

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.

avatar
Jan 9th 2024

duplicate of #5256

avatar
Jan 9th 2024

I think you closed this issue too quickly, I can reproduce these detached nodes even when hoistStatic is set to false.

avatar
Jan 9th 2024

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).

avatar
Jan 9th 2024

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.

avatar
Jan 9th 2024

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.

avatar
Jan 9th 2024

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.

avatar
Jan 9th 2024

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.

avatar
Jan 10th 2024

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.

avatar
Jan 11th 2024

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.

avatar
Jan 11th 2024

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.