963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
3.5 KiB
3.5 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | |||||
|---|---|---|---|---|---|---|---|---|---|
| KeepAlive with Transition Memory Leak | MEDIUM | Combining KeepAlive with Transition can cause memory leaks in certain Vue versions | gotcha |
|
KeepAlive with Transition Memory Leak
Impact: MEDIUM - There is a known memory leak when using <Transition> and <KeepAlive> together. Component instances may not be properly freed from memory when combining these features.
Task Checklist
- Test memory behavior when using KeepAlive + Transition together
- Consider if transition animation is necessary with cached components
- Use browser DevTools Memory tab to verify no leak
- Keep Vue updated to get latest bug fixes
The Problem
<template>
<!-- Known memory leak combination in some Vue versions -->
<Transition name="fade">
<KeepAlive>
<component :is="currentView" />
</KeepAlive>
</Transition>
</template>
When switching between components repeatedly:
- Component instances accumulate in memory
- References prevent garbage collection
- Memory usage grows with each switch
Diagnosis
Use Chrome DevTools to detect the leak:
- Open DevTools > Memory tab
- Take heap snapshot
- Switch between components 10+ times
- Take another heap snapshot
- Compare: look for growing VueComponent count
Workarounds
Option 1: Remove Transition if Not Essential
<template>
<!-- No memory leak without Transition -->
<KeepAlive :max="5">
<component :is="currentView" />
</KeepAlive>
</template>
Option 2: Use CSS Animations Instead
<template>
<KeepAlive :max="5">
<component :is="currentView" :class="{ 'fade-enter': isTransitioning }" />
</KeepAlive>
</template>
<style>
.fade-enter {
animation: fadeIn 0.3s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
Option 3: Use Strict Cache Limits
If you must use both, minimize impact with strict limits:
<template>
<Transition name="fade" mode="out-in">
<KeepAlive :max="3">
<component :is="currentView" />
</KeepAlive>
</Transition>
</template>
Option 4: Key-Based Cache Invalidation
Force fresh instances when needed:
<script setup>
import { ref, computed } from 'vue';
const currentView = ref('Dashboard');
const cacheKey = ref(0);
function switchViewFresh(view) {
currentView.value = view;
cacheKey.value++; // Force new instance
}
</script>
<template>
<Transition name="fade" mode="out-in">
<KeepAlive :max="3">
<component :is="currentView" :key="cacheKey" />
</KeepAlive>
</Transition>
</template>
Keep Vue Updated
This is a known issue tracked in Vue's GitHub repository. Memory leak fixes are periodically released, so ensure you're on the latest Vue version:
npm update vue
Key Points
- Known issue - Memory leaks with KeepAlive + Transition are documented
- Test in DevTools - Use Memory tab to verify your specific usage
- Consider alternatives - CSS animations may work without the leak
- Set strict
max- Limit cache size to cap memory impact - Keep Vue updated - Bug fixes are released periodically