Implementation Principles of Vue3 KeepAlive Component
1. The Role and Basic Concepts of KeepAlive
KeepAlive is a built-in abstract component in Vue3 used to cache inactive component instances instead of destroying them. When components are switched inside KeepAlive, their activation and deactivation lifecycle hooks are triggered, without being recreated and destroyed. This can significantly improve the performance of frequently toggled components.
2. Core Elements of the Implementation Mechanism
-
Cache Storage Structure
const cache = new Map() // Used to store component instances const keys = new Set() // Used to record the order of cache keys- Uses Map to store the mapping between keys (unique component identifiers) and component instances
- Uses Set to record key access order, implementing the LRU (Least Recently Used) eviction policy
-
Special Handling of Component Instances
- Cached component instances are marked internally (__isKeepAlive: true)
- Instances are not unmounted normally but are marked as deactivated via a special method (shapeFlag.deactivated)
3. Complete Cache Lifecycle Flow
-
Component Mounting Phase
- Check if an instance corresponding to the key exists in the cache
- If it exists: Reuse the instance directly, moving it from its original position to the latest position (marked as most recently used)
- If it doesn't exist: Create a new instance, store it in the cache, and record the key in the keys set
-
Component Switching Phase
- The currently active instance executes the deactivated lifecycle hook
- The new instance executes the activated lifecycle hook (if cached)
- Move the component's DOM to the correct container via Vue's renderer internal methods (move)
-
Cache Eviction Policy (LRU Implementation)
function pruneCacheEntry(key) { const cached = cache.get(key) if (cached) { // Execute component unmounting process but retain DOM reference unmount(cached.component) cache.delete(key) keys.delete(key) } }- When the number of cached items exceeds the max setting, evict the least recently used key (the first element in the keys set)
4. Special Lifecycle Hooks
-
onActivated
- Triggered when a cached component is displayed again
- Execution order: mounted → deactivated → activated
-
onDeactivated
- Triggered when a cached component is hidden
- Note: The component's state remains in memory, it's only removed from the DOM
5. Special Handling of DOM Operations
- When a cached component is deactivated, its DOM element is stored in a temporary container created via
document.createElement('div') - When reactivated, the DOM element is moved from the temporary container back to its actual rendering position
- This avoids the performance overhead of repeatedly creating DOM elements
6. Integration Principle with Vue Router
// Route components automatically obtain a cache key based on the route path
<RouterView v-slot="{ Component }">
<KeepAlive>
<component :is="Component" :key="$route.path" />
</KeepAlive>
</RouterView>
- Through the combination of dynamic components and keys, components of the same route path are correctly cached
- Components of different routes create separate cached instances
7. Key Implementation Techniques at the Source Code Level
- Use Symbol to mark the internal state of cached components
- Directly manipulate component subtrees via the renderer's internal methods
- Utilize JS's WeakMap to prevent memory leaks
- Quickly determine component state (activated/deactivated) via bitwise operations
This design achieves persistent caching of component state while effectively controlling memory usage through the LRU strategy, representing a classic balanced solution between performance optimization and resource management.