fix(web): recover the home screen when the bundle never runs

This commit is contained in:
jesse-ux
2026-09-22 12:13:17 +08:00
parent 6ac61be07d
commit 337d820076
18 changed files with 882 additions and 22 deletions
+24 -8
View File
@@ -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
- 复发自:无
- 修复版本:未发布(本分支未推送)