docs(tasks): home first-load fix — early reads blocked behind stylesheets (BUG-1127)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
Jesse_Chen
2026-10-01 01:28:05 +08:00
co-authored by Claude Opus 5.5
parent e600cff55f
commit 6e2f0af5a2
@@ -0,0 +1,39 @@
# TASK · 首页早发请求被样式表挡住(首页首开修复单)· 2026-10-01
> 执行方:同一 fork 子代理(产品 2026-09-30 已授权「调用 subagent 执行」)。验收:Claude。
> 分支 `codex/home-first-load-fix-20261001`,基线 `origin/staging`(≥ `e600cff5`)。沿用 BUG-1127,不新开号。
> 母单:`TASK-home-first-load-20260930.md` T8。
## 1. 验收未通过的事实
部署 `e600cff5` 后,Claude 在 staging 线上用母单 §7 的方法复测(接口统一 600 ms,两次):
| 次 | `/api/account` 等早发请求的发出时刻 | 揭幕 |
| --- | --- | --- |
| 1 | 2357 ms | 3844 ms |
| 2 | 3104 ms | 4240 ms |
本地 `next start` 下同一脚本测得早发在约 50 ms 发出。线上早发没有明显早于首屏 JS,**T8 验收第 1 条不通过**。
## 2. 根因
线上 `/` 的 HTML `<head>` 里依次是 3 个 `<link rel="stylesheet">`(位置 699 / 837 / 975),然后是异步 chunk,最后才是早发脚本(位置 5138,内联经典脚本)。按 HTML 规范,排在未加载完成的样式表之后的**内联经典脚本**要等这些样式表下载完才执行(script-blocking stylesheets)。本地样式表瞬间就到,所以测不出来;线上要多等 CSS 的下载时间。
## 3. 决策
- 早发逻辑、红线、消费方式都不变,只改脚本的装载方式,让它不再被样式表阻塞。
- staging 没有 CSP(`curl -sI /` 没有 `Content-Security-Policy`),可以用 `data:` URL。
## 4. 做法(按顺序尝试,拿到实测证据后二选一)
1. **首选**:`<script async src="data:text/javascript;base64,…">`(内容就是现在的 `bootEarlyReadsScript()`)。带 `async` 的外部经典脚本不受样式表阻塞,data URL 不需要网络往返。
2. 如果 Next / React 把它挪了位置、改了属性,或者 iOS Safari 不执行:改成放在 `public/` 下的静态小脚本(文件名带内容哈希,长期缓存,同 T3-b 的做法),`async` + `fetchpriority="high"`,并在进度记录里说明多出的那一次往返。
3. 不要改 `firstPaintFallbackBootScript` 和主题脚本,它们需要同步执行。
## 5. 验收
1. 在测量脚本里加一个「样式表慢」开关:CDP `Fetch` 拦截 `*.css`,延迟 1500 ms 再放行,其他资源正常。基线(`e600cff5`)和修复版各测 3 次,早发请求的发出时刻必须**早于第一个样式表返回**,贴对照表。
2. 用无头 Chrome 的 iPhone UA 与视口,确认 `window.__jyotishaBootReads` 已存在,并且被消费(`takeBootRead` 之后为空)。另外,把真实 iOS Safari 这一项写进 `docs/testing/home-first-load-20260930.md` 的补充步骤(环境缺口)。
3. 母单 T8 的单元测试全部保留并通过;如果脚本字符串的装载方式改变导致断言要改,写「原值 / 新值 / 原因」三栏。
4. `tsc` 0 错、`lint` 0 error、`npm test` 失败清单与基线逐条一致、`next build` 通过且 `/` 仍是 Static。
5. BUG-1127 追加「部署后复测发现被样式表阻塞 → 修复」一段;PROGRESS 母单记录追加本单一节;任务板加一行。只在分支上提交,不推送。