前言
keep-alive组件大家一定不陌生,那什么是keep-alive呢?
keep-alive
是 Vue.js 的一个 内置组件。它能够将不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实 DOM 中,也不会出现在父组件链中。简单的说,keep-alive用于保存组件的渲染状态,避免组件反复创建和渲染,有效提升系统性能。 keep-alive
的 max
属性,用于限制可以缓存多少组件实例,一旦这个数字达到了上限,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉,而这里所运用到的缓存机制就是 LRU 算法
LRU算法
LRU( least recently used)根据数据的历史记录来淘汰数据,重点在于保护最近被访问/使用过的数据,淘汰现阶段最久未被访问的数据
LRU主体思想:如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。
它的大致顺序如下:
1.新的数据插入到链表尾部;
2.如果命中缓存即链表内数据被访问,将命中的缓存移动到链表尾部;
3.链表长度满,移除链表头部数据。
LRU简易实现
LRU算法一般是通过双向链表和hashmap来实现的。js没有提供链表数据结构,但是实现了Map,所以可以用class和Map来简易实现一下。
// LRU.js
export class LRUCache {
cpacity; // 容量
cache;
constructor(cpacity) {
this.cpacity = cpacity;
this.cache = new Map();
}
get (key) {
if (this.cache.has(key)) {
let idx = this.cache.get(key);
// 先删除原先的数,再添加到末尾
this.cache.delete(key);
this.cache.set(key, idx);
return idx;
}
return -1
}
put (key, value) {
if (this.cache.has(key)) this.cache.delete(key);
else if (this.cache.size >= this.cpacity) this.cache.delete(this.cache.keys().next().value)
this.cache.set(key, value);
}
toString () {
console.log('capacity', this.cpacity)
console.table(this.cache)
}
}
// index.js
import { LRUCache } from './LRU算法.js'
const list = new LRUCache(4)
list.put(2, 2) // 入 2,剩余容量3
list.put(3, 3) // 入 3,剩余容量2
list.put(4, 4) // 入 4,剩余容量1
list.put(5, 5) // 入 5,已满 从头至尾 2-3-4-5
list.put(4, 4) // 入4,已存在 ——> 置队尾 2-3-5-4
list.put(1, 1) // 入1,不存在 ——> 删除队首 插入1 3-5-4-1
list.get(3) // 获取3,刷新3——> 置队尾 5-4-1-3
list.toString()
keep-alive
vue将dom节点抽象成了VNode节点,通过cache对象将组件的vnode缓存起来。先将满足条件的include和exclude组件缓存起来,max定义容器容量,需要重新渲染的时候将组件的vnode从cache拿出来。
过程如下:
- 声明有序集合list,存储组件的唯一标识key;
- 函数执行渲染,如果命中缓存,从有序集合list中取出组件,在list中删除key值并重新插入到队尾;
- 如果没有命中缓存,list长度已经等于max,删除队首最不常用组件的key值,并将组件key插入到list当中;
- 触发beforeMount/beforeUpdate生命周期时,缓存activated状态的组件数据和渲染状态。
结语
写的不好,各位大佬多多指教,感恩家人🙏