1.7 KiB
1.7 KiB
画布持久化经验
问题现象
用户连续编辑 2 天后关闭页面,再次打开发现:
- 素材库数据还在
- 当前画布内容丢失
- 说明问题不在素材缓存,而在画布
board持久化链路
根因
之前的实现主要依赖异步 IndexedDB 保存:
- 画布变更时调用
workspaceService.saveCurrentBoard() - 页面关闭前只尝试再次触发一次异步保存
beforeunload/visibilitychange阶段,浏览器可能直接回收页面,IndexedDB Promise 不一定有机会完成
这会导致一种典型故障:
- React 内存里的最新画布是对的
- IndexedDB 里落盘的是旧版本
- 重新打开时只从 IndexedDB 恢复,于是看起来像“画布丢了”
修复策略
采用“双写兜底”:
- 正常编辑过程仍走 IndexedDB,保持主存储不变
- 页面
beforeunload/pagehide/visibilitychange(hidden)时,同步把当前画布快照写入localStorage - 启动时比较
localStorage快照和 IndexedDB 中当前画布的updatedAt - 如果关闭前快照更新,优先恢复快照,并异步回灌到 IndexedDB
设计原则
- 不新增独立存储服务,优先在现有
App启动/保存主链路补洞 - 关闭场景必须有同步级兜底,不能只靠异步 Promise
- 恢复必须带时间戳比较,避免旧快照反向覆盖新数据
- 快照只兜底当前画布,避免扩大
localStorage占用
后续建议
- 若后面要进一步增强抗崩溃能力,可增加“低频节流快照”,而不是每次变更都同步写
localStorage - 若画布体积继续变大,需要评估快照大小上限和压缩方案
- 所有“关闭前保存”逻辑都应优先读取最新内存态,而不是重新从缓存对象拼装旧数据