fix(TransitionGroup): reset prevChildren to prevent memory leak (#13183)
ci / test (push) Waiting to run Details
ci / continuous-release (push) Waiting to run Details
size data / upload (push) Waiting to run Details

close #13181
This commit is contained in:
edison 2025-05-01 17:58:07 +08:00 committed by GitHub
parent 016c472bd2
commit 8b848cbbd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 0 deletions

View File

@ -81,6 +81,7 @@ const TransitionGroupImpl: ComponentOptions = /*@__PURE__*/ decorate({
moveClass,
)
) {
prevChildren = []
return
}
@ -110,6 +111,7 @@ const TransitionGroupImpl: ComponentOptions = /*@__PURE__*/ decorate({
})
el.addEventListener('transitionend', cb)
})
prevChildren = []
})
return () => {

View File

@ -645,4 +645,55 @@ describe('e2e: TransitionGroup', () => {
},
E2E_TIMEOUT,
)
test(
'not leaking after children unmounted',
async () => {
const client = await page().createCDPSession()
await page().evaluate(async () => {
const { createApp, ref, nextTick } = (window as any).Vue
const show = ref(true)
createApp({
components: {
Child: {
setup: () => {
// Big arrays kick GC earlier
const test = ref([...Array(3000)].map((_, i) => ({ i })))
// @ts-expect-error - Custom property and same lib as runtime is used
window.__REF__ = new WeakRef(test)
return { test }
},
template: `
<p>{{ test.length }}</p>
`,
},
},
template: `
<transition-group>
<Child v-if="show" />
</transition-group>
`,
setup() {
return { show }
},
}).mount('#app')
show.value = false
await nextTick()
})
const isCollected = async () =>
// @ts-expect-error - Custom property
await page().evaluate(() => window.__REF__.deref() === undefined)
while ((await isCollected()) === false) {
await client.send('HeapProfiler.collectGarbage')
}
expect(await isCollected()).toBe(true)
},
E2E_TIMEOUT,
)
})