diff --git a/docs/BUG/BUG-00010-推送性能与滚动优化.md b/docs/BUG/BUG-00010-推送性能与滚动优化.md new file mode 100644 index 0000000..c96be06 --- /dev/null +++ b/docs/BUG/BUG-00010-推送性能与滚动优化.md @@ -0,0 +1,111 @@ +# BUG-00010:推送性能与滚动优化 + +## 概述 + +本轮修复涵盖 BUG-00009 的实际修复实现 + 推送 Job 性能优化。 + +--- + +## D-1:点击推送按钮后列表回到顶部(滚动位置丢失) + +### 根因 + +`toggleTelegramPush` → `loadAccountsByGroup(groupId, true)` → `container.innerHTML = loading` 触发浏览器重置 `scrollTop = 0`。 + +### 修复 + +| 变更 | 文件 | +|------|------| +| forceRefresh 时不显示 loading spinner(静默刷新) | `static/js/features/groups.js` | +| 保存 scrollTop → renderAccountList → `requestAnimationFrame` 恢复 | `static/js/features/groups.js` | + +### 验证 + +手动测试:滚动到列表中间 → 点击 🔔 → 列表保持位置。 + +--- + +## D-2:游标仅在 fetch 成功时推进 + +### 根因 + +原逻辑 `finally` 块无条件推进游标 → IMAP 超时/Graph 失败时游标也前进 → 失败窗口内的邮件永远被跳过。 + +### 修复 + +移除 `finally` 块,改为 `try` 内 fetch 成功后才 `update_telegram_cursor`。异常时保留旧游标。 + +### 对应测试 + +T-21 更新为验证:IMAP 异常后游标保持原值 `"2026-03-01T00:00:00"`。 + +--- + +## PERF-1:并行获取所有账号邮件 + +### 根因 + +串行处理 5 个账号,IMAP 超时(QQ ~120s)导致整个 Job 耗时 145s,60s 轮询实际变成 ~3 分钟。 + +### 修复 + +使用 `ThreadPoolExecutor` 并行获取所有账号邮件,推送仍串行(避免 Telegram API 限流)。 + +### 效果 + +| 指标 | 优化前 | 优化后 | +|------|--------|--------| +| Job 耗时 | 145.7s | 4.0s | +| 实际轮询 | ~3 分钟 | 60 秒 ✅ | + +--- + +## PERF-2:IMAP 两步策略 + +### 根因 + +IMAP 对最后 50 封邮件逐封 `FETCH RFC822`(下载完整正文),即使大部分在游标之前需丢弃。QQ 大收件箱尤其慢。 + +### 修复 + +1. **第一步**:批量 `FETCH INTERNALDATE` 快速过滤(仅获取信封日期) +2. **第二步**:仅对 INTERNALDATE > 游标的邮件下载 `RFC822` + +### 效果 + +QQ 邮箱从 ~120s 降到 <1s(无新邮件时只执行第一步)。 + +--- + +## 调度器默认值修正 + +`_get_telegram_interval` 默认值从 600s(10 分钟)改为 60s,与前端默认设置一致。 + +--- + +## 新增测试(8 个) + +| 测试 | 描述 | +|------|------| +| test_imap_email_cst_timezone_converted_to_utc | CST +0800 → UTC 转换 | +| test_imap_email_utc_timezone_unchanged | UTC 时间保持不变 | +| test_cursor_filter_before_cursor_excluded | 游标前邮件被过滤 | +| test_cursor_filter_after_cursor_included | 游标后邮件通过 | +| test_cursor_filter_exact_cursor_excluded | 等于游标时被过滤 | +| test_cst_email_vs_utc_cursor_correct_after_fix | BUG-TG-006 核心场景 | +| test_cst_email_after_cursor_passes_filter | CST 邮件转 UTC 后通过 | +| test_d1_documented_as_manual_test | 滚动位置手动验证清单 | + +全量 211 测试通过。 + +--- + +## 提交记录 + +| Commit | 描述 | +|--------|------| +| `2d14bbd` | 滚动保留 + 游标仅成功推进 + 发送日志 | +| `f2f3c62` | 调度器默认间隔 600→60 | +| `9c838da` | ThreadPoolExecutor 并行获取 | +| `5ade471` | IMAP INTERNALDATE 两步策略 | +| `a539c77` | 静默刷新 + requestAnimationFrame |