perf(app): Phase 2 前端性能优化 5 项 — 8b-D01/D02/D03/M02/N01
Some checks failed
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled

- 8b-D01: Isar 添加 authorId+dateEpoch 复合索引和 dateEpoch 单独索引
- 8b-D02: getJournals 分页改为 DB 层 .offset().limit() 替代 Dart 层 sublist
- 8b-D03: home_bloc monthCount 改用日期范围独立查询(不受分页限制)
- 8b-M02: 笔画光栅化改为 BBox 裁剪 — 短笔画不再创建全画布尺寸图像
  - _CacheEntry 增加 offset 字段记录 BBox 偏移
  - _rasterizeStroke 计算包围盒 + 4px padding
  - _compositeIncremental 使用 offset 定位
- 8b-N01: SyncEngine enqueue 合并同一资源的操作
  - create+update → create(最新数据)
  - update+update → update(最新数据)
  - update+delete → delete
  - create+delete → 取消(不发送)
- 注意: Isar .g.dart 需运行 build_runner 重新生成
This commit is contained in:
iven
2026-06-03 16:05:11 +08:00
parent b6ffc60331
commit 32a91551c4
5 changed files with 142 additions and 40 deletions

View File

@@ -136,21 +136,77 @@ class SyncEngine {
bool get isSyncing => _status == SyncStatus.syncing;
/// 添加待同步操作到队列尾部
///
/// 合并策略8b-N01同一资源endpoint 相同)的连续操作只保留最新一条。
/// create+update → create使用最新数据
/// update+update → update使用最新数据
/// update+delete → delete资源最终被删除
/// create+delete → 取消(资源从未存在)
void enqueue(PendingOperation operation) {
_pendingQueue.add(operation);
// 查找队列中同一资源的最后一个操作
PendingOperation? existing;
for (final op in _pendingQueue) {
if (op.endpoint == operation.endpoint) {
existing = op;
}
}
if (existing != null) {
final merged = _mergeOperations(existing, operation);
_pendingQueue.remove(existing);
if (merged != null) {
_pendingQueue.add(merged);
}
// merged == null → create+delete 取消,不添加
} else {
_pendingQueue.add(operation);
}
if (_status == SyncStatus.idle) {
_status = SyncStatus.paused;
}
}
/// 批量添加待同步操作
/// 批量添加待同步操作(每个操作独立走合并逻辑)
void enqueueAll(List<PendingOperation> operations) {
for (final op in operations) {
_pendingQueue.add(op);
enqueue(op);
}
if (_status == SyncStatus.idle && _pendingQueue.isNotEmpty) {
_status = SyncStatus.paused;
}
/// 合并同一资源的两个操作
///
/// 返回合并后的操作,或 null 表示应取消create+delete
PendingOperation? _mergeOperations(
PendingOperation existing,
PendingOperation incoming,
) {
// create + delete → 取消(资源从未同步到服务端)
if (existing.type == SyncOperationType.create &&
incoming.type == SyncOperationType.delete) {
return null;
}
// create + update → create使用最新数据
if (existing.type == SyncOperationType.create &&
incoming.type == SyncOperationType.update) {
return existing.copyWith(data: incoming.data, version: incoming.version);
}
// update + update → update使用最新数据
if (existing.type == SyncOperationType.update &&
incoming.type == SyncOperationType.update) {
return incoming;
}
// update + delete → delete
if (existing.type == SyncOperationType.update &&
incoming.type == SyncOperationType.delete) {
return incoming;
}
// 其他组合delete+create, create+create 等)不合并
return incoming;
}
/// 检查网络状态并尝试同步全部待处理操作