KeepAlive + Transition + v-if 同时使用时会导致时会导致内存泄漏的2个bug
wcldyx opened this issue · comments
Vue version
3.4.21
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-futfv6?file=src%2FApp.vue
Steps to reproduce
测试的时候注意自己创建一个新项目测试,因为stackblitz上看内存占用不方便
有两个bug
第一个bug: KeepAlive + Transition + v-if 同时使用时会导致时会导致内存泄漏。
如图所示,通过点击toggle按钮用v-if 不停的切换显示隐藏组件,你会看到内存一直没有被释放。
单独使用KeepAlive 时在通过v-if隐藏组件时内存会自动释放。
第二个bug: 在 mode="out-in"时通过v-if切换并同时移除include里面的key时,对应的组件没有被正常卸载(没有触发onUnmounted), 内存也没有得到释放。
mode为默认值时,组件能正常卸载
mode="out-in" 时,组件没有被正常卸载
What is expected?
修复以上bug
What is actually happening?
KeepAlive + Transition + v-if 同时使用时会导致时会导致内存泄漏,同时在 Transition 的 mode="out-in"时,组件没有被正常卸载或销毁
System Info
No response
Any additional comments?
No response
以下是完整代码
<script lang="ts" setup>
import { ref, defineComponent, h, onUnmounted } from 'vue';
// import A from "./A.vue";
const show = ref(true);
const include = ref(['A']);
const A = defineComponent({
name: 'A',
setup() {
const list = ref(new Array(1000000).fill({ name: 'hello' }));
console.log('安装');
onUnmounted(() => {
console.log('卸载');
});
return () => h('h1', 'A组件' + list.value.length);
},
});
function toggle() {
show.value = !show.value;
if (show.value) {
include.value = ['A'];
} else {
include.value = [];
}
}
</script>
<template>
<div>include:{{ include }}</div>
<button @click="toggle">toggle</button>
<Transition mode="out-in">
<KeepAlive :include="include">
<A v-if="show" />
</KeepAlive>
</Transition>
</template>
@wcldyx 这是因为在开发环境会在元素上定义 __vnode
,公开给 vue-devtools
使用。生产环境不会内存溢出
core/packages/runtime-core/src/renderer.ts
Lines 697 to 706 in 3bf34b7
@wcldyx 这是因为在开发环境会在元素上定义
__vnode
,公开给vue-devtools
使用。生产环境不会内存溢出core/packages/runtime-core/src/renderer.ts
Lines 697 to 706 in 3bf34b7
6啊,你是怎么定位到这个问题的
Leave it open because the PR for the second issue has not yet merged