fix(web): 次级页稳定外壳与缓存预取,跨部署导航自愈(BUG-966/967)

This commit is contained in:
jesse-ux
2026-09-18 18:45:48 +08:00
parent dccedf372e
commit 9ccb65b71f
25 changed files with 1066 additions and 160 deletions
@@ -0,0 +1,75 @@
# 真机清单 · 次级页进入不再推挤 + 跨部署导航自愈(2026-09-18
对应 `TASK-secondary-page-entry-20260918.md``PROGRESS-secondary-page-entry-20260918.md`、BUG-965 / 966 / 967。
自动化做不到的部分:需要**浏览器 + 已登录账号**。执行环境无 Chrome、无登录态,因此这些是环境缺口,不是「已通过」。
准备:桌面 Chrome,宽度 ≥ 1024px,已登录。DevTools → Network 勾上 `Preserve log`
## A · 进入三页时外壳高度不变(BUG-966)
1. 停在 `/`。Console 里先贴:
```js
(() => {
const measure = () => {
const node = document.querySelector(".secondary-page");
if (!node) return null;
const r = node.getBoundingClientRect();
return { h: Math.round(r.height), top: Math.round(r.top) };
};
const log = [];
const obs = new ResizeObserver(() => log.push({ t: performance.now(), ...measure() }));
const start = () => {
const node = document.querySelector(".secondary-page");
if (!node) { requestAnimationFrame(start); return; }
obs.observe(node);
log.push({ t: performance.now(), ...measure(), event: "first" });
};
window.__secondaryPageLog = log;
window.__secondaryPageStop = () => { obs.disconnect(); console.table(log); };
document.addEventListener("click", (event) => {
const a = event.target.closest("a[href='/chart'], a[href='/ephemeris'], a[href='/reports']");
if (a) requestAnimationFrame(start);
}, true);
console.log("ready: click 星盘 / 星历 / 我的报告, then __secondaryPageStop()");
})();
```
2. 点侧栏「星盘」。内容出现后立刻在 Console 执行 `__secondaryPageStop()`。
- **期望**:表格里所有 `h` 相同(等待态与内容态同高),`top` 不变。
- **不期望**:高度从一行文案跳到整页正文;出现转圈、骨架、「正在加载」。
3. 对「星历」「我的报告」各做一次。三页的等待句可以不同(盘还没拿到 / 星历还没拿到 / 报告列表还没拿到),但都必须写在 `.secondary-page` 里居中,不能是矮块。
## B · 第二次进入没有等待句(BUG-966 缓存)
1. 打开过「星盘」并等到盘出现。
2. 点「新建对话」回 `/`(不要刷新)。
3. Network Clear,再点「星盘」。
- **期望**:第一帧就是盘(或失败句),**没有**「这一张盘还没拿到。」。Network 里可以有一条后台 `/api/chart-view`(静默刷新)。
4. 「星历」「我的报告」同样:第二次不得再出现各自的等待句。
## C · 悬停会预取数据(BUG-966 预取)
1. 刷新 `/`Network Clear,筛选 `chart-view|ephemeris|reports`。
2. 鼠标移到侧栏「星盘」上,**先不要点**。
- **期望**:出现 `GET /api/chart-view`。对「星历」「我的报告」分别是 `/api/ephemeris`、`/api/reports`。
3. 再点进去。
- **期望**:若预取已完成,进页不再先闪等待句。
## D · 跨部署旧标签页会在下一次跳转整页重载(BUG-965 / 967
这一条必须跨一次真实部署,属环境依赖。
1. 在 staging 打开 `/` 并停留在对话页(不要关标签)。确认对话还能发、还能收。
2. 让负责人发一版新的 staging(或等下一轮门禁部署)。记下新 SHA。
3. **不要刷新**这个旧标签。切到别的应用再切回来(触发 `visibilitychange`)。
4. Network Clear。点侧栏「星盘」。
- **期望**:出现 Type = `document` 的 `/chart` 请求(整页重载),页面打开;不是点击无反应。
- 地址栏最终是 `/chart`,之后再点「星历」应走客户端导航(没有新的 document 请求),因为这时已经是新构建。
5. 另开一个**部署之后**才打开的新标签,点「星盘」。
- **期望**:没有 document 请求(版本一致,仍是客户端路由)。
6. 若 health 接口人为断掉(DevTools Offline 只挡 `/api/health` 不挡其它):
- **期望**:当前标签继续能点、不强制刷新。
失败时记下:点击时的 URL、Console 全文、Network 里 `/_next/static` 与 `/chart?_rsc` 的状态码。不要把用户资料贴进仓库。