LocalStorage 本身不支持自动清理和LRU机制,需手动维护访问顺序并结合大小估算实现淘汰逻辑;关键设计包括用索引数组模拟访问队列、独立管理元数据、预估UTF-8字节数、防错更新index及主动预清理。

LocalStorage 本身不支持自动清理,也没有内置的 LRU(最近最少使用)机制。要让它配合 LRU 算法清理缓存,核心是手动维护访问顺序 + 主动触发淘汰逻辑,而不是依赖浏览器行为。
LocalStorage LRU 清理的关键设计点
- 不能只看条目数量:5MB 容量下,一个大 JSON 就可能占掉大部分空间,所以清理必须结合「大小估算」和「使用顺序」。
-
时间戳不是唯一解:单纯存
Date.now()容易因多标签并发写入导致错乱,更稳妥的是用索引数组模拟访问队列。 -
元数据必须独立管理:把 key 的访问顺序、数据大小等信息存在单独的 key(如
cache:index、cache:sizes)里,避免污染业务数据。
如何实现一套轻量可靠的 LRU 清理逻辑
-
封装一个
LruStorage类,统一处理 set/get/prune 操作-
set(key, value):序列化后存入cache:data:${key};同时更新cache:index数组(去重 + 置顶);记录该 key 占用字节数到cache:sizes -
get(key):先读cache:data:${key},若存在则将 key 移至cache:index开头,再返回解析结果 -
prune():按cache:index末尾顺序,逐个删除对应 data 和 size 条目,直到总大小 ≤ 预设阈值(比如 4.5MB)
-
-
用
encodeURIComponent(JSON.stringify(value)).length近似计算 UTF-8 字节数- 比
JSON.stringify(value).length更准,能反映真实存储开销 - 把每个 key 的 size 存在
cache:sizes对象里,方便快速排序和批量清理
- 比
-
index 更新要防出错
立即学习“Java免费学习笔记(深入)”;
- 每次操作前先
filter掉旧 key,再unshift新 key,避免重复 - 初始化时确保
cache:index是空数组[],而非null或undefined - 所有 JSON 操作都包
try/catch,防止元数据损坏导致整个缓存不可用
- 每次操作前先
实际清理时的判断依据
- 不建议等
QuotaExceededError才清理 —— 那已经是最后一刻,用户体验已受损 - 推荐在每次
set前预估新增体积,若当前总大小 + 新增 ≥ 4.8MB,就先prune() - 也可以定时检查(比如每 10 次写入触发一次),或监听关键操作(如用户退出、页面卸载前)
替代方案:如果不需要严格 LRU,可以更简单
-
FIFO 模式:用
cache:queue存 key 列表,每次push(key),清理时shift() -
TTL 模式:存
{ value, expires },读取时校验Date.now() > expires,过期即删 - 两者实现成本低,适合配置类、状态同步类缓存,不追求高命中率场景
不复杂但容易忽略


















