Files
TrueGrowth/docs/BOARD_PERSISTENCE_LESSONS.md

1.7 KiB
Raw Blame History

画布持久化经验

问题现象

用户连续编辑 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
  • 若画布体积继续变大,需要评估快照大小上限和压缩方案
  • 所有“关闭前保存”逻辑都应优先读取最新内存态,而不是重新从缓存对象拼装旧数据