Files
TrueGrowth/docs/BOARD_PERSISTENCE_LESSONS.md

46 lines
1.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 画布持久化经验
## 问题现象
用户连续编辑 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`
- 若画布体积继续变大,需要评估快照大小上限和压缩方案
- 所有“关闭前保存”逻辑都应优先读取最新内存态,而不是重新从缓存对象拼装旧数据