Files
Jyotisha/PROGRESS-unified-loading-20260902.md
T
Jesse_Chen 482796fc52 fix(chat): reveal the home page once after a two-phase bootstrap
The loading screen now owns every wait: starter questions, today's
starlanguage and the rectification entry summary are fetched in a prepare
phase before reveal (4s budget, static fallbacks), the rectification chunk is
warmed, recent sessions are prefetched, and no component spinner remains
after the page appears. BUG-479.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-02 04:39:04 +00:00

4.6 KiB
Raw Blame History

PROGRESS · 首页加载统一:一次等待、一次揭幕(2026-09-02)

分支:codex/unified-loading-20260902 基线:origin/staging @ 02f06255,并先行合入 codex/streaming-ux-20260901 @ c846c44a(任务书前置条件;合并无冲突,merge commit 25e3094f)。本轮改动写在合并后的代码形态上。

执行方:Claude(用户 2026-09-02 明示"直接开始执行")。

结论

登录后只有一次揭幕。加载屏两阶段(载入账户 → 准备对话),阶段二并行取推荐问题、今日星语、校正入口摘要并预热校正分包;全部就绪或 4 秒到期才揭幕;揭幕后首页无任何组件级 spinner / busy / "正在…"文案(流式生成中除外)。

与任务书的差异

  • 当前会话消息:合入的流式分支已把 fetchSessionDetail 前移到 setHydrated 之前(page.tsx 启动 effect),本轮不再重复做,只把它计入"阶段二"的语义说明。
  • 阶段二实现方式:没有把三个请求搬进启动 effect 的 Promise.allSettled,而是把三个既有 effect 的门槛从 hydrated 改为 bootstrapPhase"account" → "prepare"),再用一个揭幕 effect 汇总就绪状态。理由:三个 effect 各自带重试/身份守卫/缓存逻辑(推荐问题的 onboardingRequestIdentity、今日星语的当日缓存与一次重试),原样复用不会产生重复请求,也不必复制这些逻辑。合同测试锁 bootstrapPhase === "account" || !accountId 门槛恰为 3 处。
  • 今日星语的 pending 文案:任务书写"非个性化文案";实际采用与 unavailable 相同的静态句「今天的星语还没写出来。」,到达后静默替换。原「正在写下今天的星语。」删除。

改动清单

文件 内容
src/lib/home-bootstrap.ts(新) BootstrapPhaseBOOTSTRAP_PREPARE_TIMEOUT_MS = 4000SESSION_PREFETCH_COUNT = 5bootstrapPrepareSettledbootstrapRevealDelayMsbootstrapLoadingCopysessionIdsToPrefetch
src/app/page.tsx bootstrapPhase / rectificationEntrySummarySettled state、prepareStartedAt reffinally 里成功路径改 setBootstrapPhase("prepare")(失败仍 setHydrated(true));三个 effect 门槛与依赖改为 bootstrapPhase;入口摘要 effect 加 finally 置 settled;新增揭幕 effect(就绪或超时)、分包预热 effect、揭幕后预取 effect;加载屏文案按阶段;删 starter-loading 分支、dailyStarlanguageBusyInlineSpinner import 与会话切换 spinner
src/components/starter-home.tsx dailyStarlanguageBusy prop 与 aria-busy
src/app/globals.css 删两处 .starter-loading 定义(已无使用)
DESIGN.md §9 整页阻塞行改为"两阶段载入";补首页揭幕规则段
tests/home-bootstrap-reveal.test.ts(新) 7 条:纯函数 + 源码合同
tests/daily-starlanguage.test.ts 例外条款:effect 切片标记改为新门槛与新依赖(原值 !hydrated ... / [..., hydrated, ...]);aria-busy={dailyStarlanguageBusy} 正断言改为不存在(原值见注释)
tests/starter-questions.test.ts 例外条款:守卫切片终点由 "(onboardingPending ?" 改为 "<StarterHome"(原值见注释)
docs/BUG_HISTORY.md BUG-479

onboardingPending 变量保留(滚动 effect 与 productEntrypointsDisabled 仍用),只是不再驱动渲染分支。

验证(本机,无 Docker

  • ./node_modules/.bin/tsc --noEmitexit 0。
  • npm run lint0 error72 warning,全部既有;本轮改动文件无新增 warning)。
  • npm test2493 条,pass 2459 / fail 24 / skipped 1024 条失败清单与 551d6317 基线逐字相同(数据库/部署类既有环境缺口),无新增。
  • Python quick-gate 前端契约四文件:24 passed。
  • next build(默认 Turbopack):exit 0┌ ○ / Static。
  • 首屏 JS gzip-9(预渲染 index.html 引用的 /_next/static/**.js 去重后求和):合并点 25e3094f 基线 513,570 B → 本轮 513,889 B+319 B / +0.06%(±2% 内)。

未做 / 待用户

  • 无登录态:登录后单次揭幕、Slow 3G 下 4 秒兜底揭幕、切换会话零 spinner 均未在浏览器实测,由合同测试覆盖。建议照 docs/testing/staging-manual-walkthrough-20260901.md 加一条:DevTools 节流 Slow 3G 刷新首页,加载屏应出现"正在准备对话"文案,最多约 4 秒后一次进入完整界面,进入后无任何转圈。
  • 本分支包含 codex/streaming-ux-20260901 的合并;合入 staging 时会一并带入该分支(其独立验收见该轮记录)。