Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
6.4 KiB
6.4 KiB
TASK · 从其他页面回首页不再重放加载动画(2026-09-26)
基线
origin/staging当前 head(线上e84d6eb8)。分支codex/home-warm-return-20260926。- 串行:本单改
frontend/src/app/(app)/page.tsx与frontend/src/lib/home-bootstrap-run.ts,与TASK-new-chat-from-people-20260926.md(BUG-1038,同样改新建意图与启动落点)冲突 → BUG-1038 合入后开工。与TASK-people-ephemeris-ui-20260926.md不交叉。
事故实证(产品 09-26 真机)
第一次进首页有加载动画是预期;但从星盘 / 星历 / 我的报告 / 星盘档案点「新建对话」回首页,每次都要再看一遍加载动画、等很久。
代码链(origin/staging e84d6eb8):
page.tsx:const [hydrated, setHydrated] = useState(false)、const [bootstrapPhase, setBootstrapPhase] = useState<BootstrapPhase>("account")—— 每次挂载都从"未就绪"开始,渲染AppLoadingIndicator。home-bootstrap-run.tsrunAccountPhase:每次挂载都重新fetchModelCatalog(/api/models)、fetchActiveConsultationStatus(/api/consult/status),await sessionListReady(共享外壳里已就绪,快),resolveLanding中可能再fetchSessionDetail。- 之后进入 prepare 阶段:
page.tsx拉/api/rectification/cases/entry-summary,daily-starlanguage-binder.tsxfetchDailyStarlanguage,揭幕预算BOOTSTRAP_PREPARE_TIMEOUT_MS = 4000。 - 合计:回首页一次要 3–5 次网络往返 + 最多 4 秒揭幕等待。这些数据在本次打开里第一次进首页时已经拿过。
- 先例:BUG-966 让星盘 / 星历 / 报告首屏数据进模块级缓存,"同一会话再次进入直接用模块缓存,不重放等待"(DESIGN §Secondary page shell)。首页没有同等机制。
根因
首页的"一次等待一次揭幕"是按组件挂载计的,不是按这次打开网页计的;客户端导航回首页会卸载重挂,于是每次重放完整启动。
决策记录(产品 2026-09-26)
- D1 加载动画每次打开网页只放一次:整页加载(刷新、首次打开、登录后跳转)照旧有加载动画;同一次打开里从其他页面客户端导航回首页,不出现加载动画,首页立即可用。
- D2 模块级"首页暖快照"(新文件
frontend/src/lib/home-warm-snapshot.ts,按账户 id 键,只存内存、不落 localStorage):第一次启动成功后写入 ——modelCatalog、account、profile、startGreeting所需信息、onboardingStep、校正入口摘要、今日星语(按当前人物 + 日期键)。 - D3 暖返回路径:挂载时若有同账户快照 →
hydrated/bootstrapPhase的初始值直接取就绪态(用useState(() => …)初始化函数,不新增 hook),同步完成落点(含新建意图,沿用 BUG-1038 合并后的唯一解析);随后后台刷新模型列表、后台任务状态(有进行中的咨询仍要恢复)、入口摘要、今日星语,结果到了再静默替换,不回到加载态、不出 spinner。 - D4 失效:账户变化、登出、
/api/account401 → 清空快照;模型列表后台刷新发现当前所选模型已下线 → 沿用现有「此前选择的模型已下线,已切换为默认模型」提示;今日星语跨日或换人 → 该字段按新键重取(卡片区用现有静态句,不挡首页)。 - D5 打开历史会话(从次级页侧栏点某条历史
/?c=<id>):同样不放加载动画;会话消息沿用首页内切换会话时的现有加载方式,不新造等待态。
硬红线
- 整页加载的行为与文案不变(加载环、20 秒错误屏、局部重试、BUG-1021 的"不半揭幕")。暖返回只在快照齐全时启用,缺任何一项就走原冷启动路径,不得出现"揭幕了但模型 / 资料没填"的半状态。
- 进行中的咨询恢复(
reservedConsultation/ pending)在暖返回时仍要执行,只是改为后台检查。 Home()不新增useState/useRef(用初始化函数与模块快照);page.tsx不得增长超过增长合同;新逻辑放lib/,内部不调用 React hook。- 快照只在内存、按账户隔离,不落任何持久存储;不缓存消息正文以外的敏感数据到新位置(消息仍在现有会话状态里)。
/保持○ Static,首屏 gzip ±2%;全量测试 Node 22 + Linux 与基线逐条一致、新增 0;改动断言写三栏(在测试文件里)。- 必须在真实浏览器里测:首页 → 星盘 → 点「新建对话」,录网络面板:暖返回时在首页可交互之前没有任何被等待的网络请求,也没有加载环;截图 / 数字写进 PROGRESS。
任务分解
- T1
home-warm-snapshot.ts(写入、读取、按账户失效、按人物 + 日期键的今日星语)。验收:纯函数单测覆盖写入 / 换账户清空 / 401 清空 / 跨日重取。 - T2 冷启动成功后写快照;挂载时读快照走暖路径(D3),后台刷新与静默替换。验收:真实 React 生命周期测试——先冷启动一次 → 卸载 → 以
/?new=1重挂:首帧即为就绪态(无AppLoadingIndicator),新建空对话已激活,fetchModelCatalog未被 await(后台调用可有);快照缺一项时回落冷启动。 - T3 后台刷新的各种结果:模型下线提示、进行中咨询恢复、今日星语换日 / 换人、入口摘要更新。
- T4 记录:BUG-1040(回首页重放加载,关联 BUG-966 / 479 / 1021);
frontend/DESIGN.md§9 首页揭幕规则写明"每次打开网页只揭幕一次,客户端返回首页走暖快照";CHANGELOG;PROGRESS(含网络面板记录);docs/testing/home-warm-return-20260926.md(首页→星盘→新建对话无加载环;首页→报告→点历史会话无加载环;刷新首页仍有加载环;登出换账号后不串数据;跨日回首页今日星语更新)。
开工前置命令
git fetch origin --prune
git log --oneline origin/staging | grep -i "1038\|new chat" | head # 确认 BUG-1038 已合入
node -v # 22.x
git worktree add -b codex/home-warm-return-20260926 .worktrees/home-warm-return-20260926 origin/staging
cd .worktrees/home-warm-return-20260926/frontend && npx tsx --test tests/home-bootstrap-run.test.ts tests/home-bootstrap-reveal.test.ts
BUG 编号
写单时 BUG-1038 / 1039 已被同日两单预留;本单 BUG-1040,开工时核对。