fix(web): recover the home screen when the bundle never runs
This commit is contained in:
+24
-8
@@ -12232,9 +12232,9 @@
|
||||
|
||||
## BUG-936 | 首页永远停在「正在载入账户」,没有超时也没有报错
|
||||
|
||||
- 状态:investigating
|
||||
- 状态:兜底已补、根因待分流
|
||||
- 首次发现:2026-09-17
|
||||
- 最近更新:2026-09-17
|
||||
- 最近更新:2026-09-22
|
||||
- 影响面:`/` 首屏揭幕(`app/page.tsx` 的 `!hydrated || (!account && !accountError)` 门)、`AppLoadingIndicator`、`app/layout.tsx`
|
||||
- 用户现象:产品负责人转述,一位已有账号的用户在 iPhone Safari 打开 `https://staging.jyotisha.chat/`,永远停在「正在载入账户 / 同步个人资料与对话记录」,进不去页面。转圈动画还在动。
|
||||
- 触发条件:尚未定位到具体条件。已排除接口侧。
|
||||
@@ -12246,13 +12246,13 @@
|
||||
5. 线上 bundle 的语法下限是 **Safari 16.4**:`1stw4tc266s7a.js`(Next 自己的 app-router 运行时)含类静态块 `class y extends Component{static{this.contextType=...}}`;`089-80cjt8-1t.js`(本仓中文断句 `split(/(?<=[。!?;;])\s*/)`)与 `0dmsli_y64717.js`(链接识别依赖)含正则后行断言。两者在 Safari < 16.4 都是**解析期** SyntaxError,core-js 这类运行时 polyfill 救不了。
|
||||
6. 该下限不是新引入:`next: 16.3.1` 从仓库首个提交 `4aa0105f`(2026-07-15)就在。所以如果这台设备以前能用,(5) 不是本次原因。
|
||||
- 待定位(需要用户侧一条信息即可分流):① 设备 iOS 版本 < 16.4 → 命中 (5);② 某个 chunk 在弱网下没下全或被内容拦截器挡掉 → 无痕窗口 / 清除网站数据后恢复;③ Safari 缓存里留着坏掉的 chunk(chunk 带 `cache-control: public, max-age=31536000, immutable`)。
|
||||
- 根因:未确认,不得提前写。
|
||||
- 修复:未做。
|
||||
- 验证:未做。
|
||||
- 防复发(已可确定的一条,独立于根因):首屏不得把「出错了」的唯一出口放在可能失败的模块 bundle 里。根 layout 需要一段与 bundle 无关的内联经典脚本,在 hydrate 超时或语法不支持时把这一屏换成可读的提示与「重新加载」。见 `docs/tasks/TASK-first-paint-dead-screen-fallback-20260917.md`。
|
||||
- 相关记录:BUG-716(`/chart` 白屏 45 秒,另一条链路)
|
||||
- 根因:未确认,不得提前写。兜底补上不等于这台 iPhone Safari 已经修好。
|
||||
- 修复:根 layout 增加一段与 bundle 无关的内联经典脚本。13 秒后,若仍有 `.app-loading` 且 `<html data-hydrated>` 不是 `"1"`,把加载内容换成「这个页面没能加载完」和只在点击时刷新的「重新加载」。揭幕成功后由首页装配 hook 写 `data-hydrated="1"`,正常路径不闪这一屏。匿名标记只留类别、构建标识和耗时,不留异常原文或请求体。接口超时仍走 bundle 里原来的「连接云端服务超时」,不并进这一屏。本仓断句的后行断言另见 BUG-998,那一项不能把 Next 运行时的语法下限降到 Safari 16.4 以下。
|
||||
- 验证:`frontend/tests/first-paint-fallback-contract.test.ts` 锁定 ES5、超时大于 8000+4000、未揭幕才替换、按钮才刷新,以及 hydrate 超时 / chunk 404 / 解析失败 / 旧缓存 / 弱网 / 接口错误六类不互相冒充。未在 iPhone Safari 或断 chunk 的浏览器里走查。
|
||||
- 防复发:首屏不得把「出错了」的唯一出口放在可能失败的模块 bundle 里。不得自动刷新。见 `docs/tasks/TASK-home-bootstrap-reliability-20260922.md` 与 `docs/testing/home-bootstrap-reliability-20260922.md`。
|
||||
- 相关记录:BUG-716(`/chart` 白屏 45 秒,另一条链路)、BUG-998
|
||||
- 复发自:无
|
||||
- 修复版本:未发布
|
||||
- 修复版本:未发布(本分支未推送,不得声称 staging 已部署)
|
||||
|
||||
## BUG-937 | 咨询第 0 步 `toolChoice: required` 让全部咨询整轮失败
|
||||
|
||||
@@ -13215,3 +13215,19 @@
|
||||
- 相关记录:BUG-001、BUG-010、BUG-011、BUG-018、BUG-073、BUG-076、BUG-188
|
||||
- 复发自:无
|
||||
- 修复版本:本次分支提交(未推送,未部署)
|
||||
|
||||
## BUG-998 | 本仓中文断句使用正则后行断言,Safari 16.4 以下在解析期失败
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-17(写在 BUG-936 的已确认事实里,当时未单独编号;BUG-937 / BUG-938 已被咨询故障占用)
|
||||
- 最近更新:2026-09-22
|
||||
- 影响面:`frontend/src/lib/sentence-split.ts`;原先后行断言在个人报告断句、校正开场句、引擎含义展示、采用旁白、采集提示、轮次旁白
|
||||
- 用户现象:无单独的用户报告。若设备 Safari 低于 16.4,含后行断言的 chunk 会在解析期抛出 SyntaxError,React 不会 hydrate。这不能解释「以前能用、这次不能用」的设备,也不能单独修好 BUG-936。
|
||||
- 触发条件:浏览器解析本仓断句 chunk,且不支持正则后行断言。
|
||||
- 根因:八处 `split` 使用后行断言来「在句末标点后切开并保留标点」。这是语法,不是运行时 polyfill 能补的。
|
||||
- 修复:共用 `splitAfterSentencePunctuation`,用手写扫描在标点后切开并保留标点。`frontend/src` 不再出现后行断言。Next 运行时里的类静态块改不了,语法下限仍是 Safari 16.4。
|
||||
- 验证:`frontend/tests/sentence-split.test.ts` 用表驱动用例和旧正则对照,确认切开结果逐字一致;源码合同扫描 `frontend/src` 无后行断言。校正与报告的既有断言未改。
|
||||
- 防复发:`frontend/src` 不得再写后行断言。测试文件可以保留旧正则作对照。
|
||||
- 相关记录:BUG-936
|
||||
- 复发自:无
|
||||
- 修复版本:未发布(本分支未推送)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# PROGRESS · 首页加载失败可恢复性(2026-09-22)
|
||||
|
||||
工作树:`.worktrees/home-bootstrap-reliability-20260922`
|
||||
分支:`codex/home-bootstrap-reliability-20260922`
|
||||
开工时 `origin/staging` = `10baeb2fa865743c428806e115ac92ca9d92fb71`。未 push。未改 `page.tsx`。
|
||||
|
||||
既有 `TASK-first-paint-dead-screen-fallback-20260917.md` 尚未合入。本分支按它的未完成项做了唯一一套内联兜底,并完成断句后行断言清理。不另写一份 first-paint 进度。
|
||||
|
||||
## T1 兜底
|
||||
|
||||
- 根 layout 在主题脚本旁增加 `firstPaintFallbackBootScript()`。生成结果是经典 `<script>`:无 `type="module"`,无 `=>` / `const ` / `let ` / `class ` / 模板串 / `?.` / `??`。
|
||||
- 触发:`setTimeout` **13000ms**(大于 `page.tsx` 的 8000 与准备揭幕的 4000)。回调里仍有 `.app-loading` 且 `documentElement` 的 `data-hydrated` 不是 `"1"` 时,替换 `.app-loading-content`。
|
||||
- 文案:标题「这个页面没能加载完」,正文说明网络中断或浏览器过旧,并提示清除 Safari 本站数据或升级到 iOS 16.4 以上。唯一按钮「重新加载」,只在点击时 `location.reload()`。
|
||||
- 揭幕标记写在 `useHomeShellRegistration`:`hydrated` 为真时设 `document.documentElement.dataset.hydrated = "1"`。`Home()` 未加 `useState` / `useRef`,`page.tsx` 未改。
|
||||
- 复用 `.app-loading-error` 卡片,没有第二套转圈或骨架。
|
||||
|
||||
## T2 分流
|
||||
|
||||
六类不并成「接口慢」:`hydrate-timeout`、`chunk-404`、`chunk-parse`、`stale-cache`、`weak-network`、`api-error`。前五类可以由内联脚本在 bundle 没跑起来时标记;`api-error` 仍是 bundle 里的「连接云端服务超时」那一屏。匿名对象只有 `category`、`buildId`、`durationMs`。
|
||||
|
||||
真人清单:`docs/testing/home-bootstrap-reliability-20260922.md`。BUG-936 改为「兜底已补、根因待分流」,未标 resolved。低版本 Safari 与真实 chunk 失败未在浏览器验收。
|
||||
|
||||
## T3 后行断言
|
||||
|
||||
`frontend/src` 已无 `(?<=`。共用 `splitAfterSentencePunctuation`。表驱动用例覆盖中文句号、问号、叹号、分号、英文标点、换行、连续标点、结尾无标点,并与旧正则逐字对照。既有校正与报告断言未改。另立 BUG-998(不占用 996 / 997 / 999)。
|
||||
|
||||
## 验证
|
||||
|
||||
定向测试(未跑全量 `npm test`,未跑 `next build`):
|
||||
|
||||
| 命令 | 结果 |
|
||||
| --- | --- |
|
||||
| `npx tsx --test tests/sentence-split.test.ts tests/first-paint-fallback-contract.test.ts` | 6 pass / 0 fail |
|
||||
| `npx tsx --test tests/home-shell-growth-contract.test.ts tests/agent-voice-copy-contract.test.ts tests/rectification-collect-prompt.test.ts tests/rectification-adopt-narration-20260904.test.ts` | 48 pass / 0 fail |
|
||||
| `.\node_modules\.bin\tsc --noEmit` | 0 错 |
|
||||
| `npm run lint` | 0 error / 119 warning(既有 warning,未顺手改) |
|
||||
|
||||
`home-shell-growth-contract` 通过,因此 `Home()` 的 `useState` / `useRef` 没有超过现有上限,行数也没有超过粗护栏。
|
||||
@@ -0,0 +1,23 @@
|
||||
# 真人 / 模拟清单 · 首页加载失败可恢复(2026-09-22)
|
||||
|
||||
BUG-936 的根因还没定。下面能做的是看兜底是否出现、点了是否只刷新一次。低版本 Safari 和故意弄坏 chunk 的浏览器检查是环境缺口,不是通过。
|
||||
|
||||
兜底补上不等于每个 Safari 用户都已修好。要完成分流,仍需要当事人的 iOS 版本,以及无痕窗口或清除本站数据之后是否恢复。
|
||||
|
||||
## 本机可以模拟
|
||||
|
||||
1. 打开首页 HTML。在开发者工具里把后续脚本请求阻断,或在元素面板里留下 `.app-loading` 且不要给 `<html>` 加上 `data-hydrated="1"`。等超过 13 秒。
|
||||
2. 应看到标题「这个页面没能加载完」,正文说明网络中断或浏览器版本过旧,并提示 Safari 清除本站数据或升级到 iOS 16.4 以上。只有一枚「重新加载」。页面不会自己刷新。
|
||||
3. 点「重新加载」才整页刷新。再停在同一屏时,仍然不会自动连刷。
|
||||
4. 正常打开现代浏览器的首页:揭幕完成前不要闪出上面这句。揭幕后轨道环不再出现。
|
||||
5. 把网络掐断后,如果客户端 bundle 已经跑起来并在 8 秒内失败,仍应是原来的「暂时无法进入 Jyotisha / 连接云端服务超时」,不要换成死屏这句。这两种失败不是同一件事。
|
||||
|
||||
## 环境缺口(本轮未做,不能写成通过)
|
||||
|
||||
- 没有当事人的 iPhone。不知道 iOS / Safari 版本,也不知道清除网站数据或无痕窗口之后是否恢复。BUG-936 根因因此仍是「待分流」。
|
||||
- 没有一台 Safari 16.4 以下的设备。本仓断句已经去掉后行断言,但 Next 运行时仍有类静态块,低版本 Safari 仍可能在解析期失败。本清单不能证明那一类设备已经能进首页。
|
||||
- 没有在已构建页面上故意把某个 `/_next/static/chunks/*.js` 改成 404 或截断后再用真实浏览器等 13 秒。自动化只在假 DOM 里跑过这段内联脚本。
|
||||
|
||||
## 不该看到的东西
|
||||
|
||||
兜底文案、按钮和 `data-bootstrap-failure` 都不写异常原文、出生资料、token 或请求体。观察标记如果出现,只有类别、构建标识和耗时。
|
||||
Reference in New Issue
Block a user