# 首页 3D pet 回归与 review

日期：2026-10-17。范围：`home-race-pets.js`、角色移动/视线接入、资源加载和预算。正式网站导航、原生 App pet 包不在本次变更范围。

## 验证计划

环境为隔离 Chrome profile、localhost 正式网站；造型检查独立加载同一正式模型模块。使用程序几何，不调用外部生成服务。Web-only 变更不运行 Swift/Xcode 构建。

| 风险 | 可观测通过条件 | 证据 |
| --- | --- | --- |
| 角色身份、遮挡、脚步方向 | 正/侧/背面保留角色特征；分帧抬脚回摆、支撑脚接地 | model views + gait frames |
| 3D 转向、移动、视线 | 两个模型 lane、heading、gaze、foot pose 随路径改变；瞳孔方向与前方目标一致 | 模型方向断言 + runtime samples |
| 真实拾取驱动 Island | 两轮自然奔跑及手动放置均有 collision、Island 状态变化 | events + screenshots |
| 持续运行资源增长 | 两轮后的 geometry/texture 与 heap 不持续增大；atlas 请求为 0 | resource/heap snapshots |
| 生命周期 | 暂停、离屏、后台、Reduce Motion 同时冻结位移和姿态；恢复继续 | browser assertions |
| 移动端 | 390px/320px 无横向溢出，角色、工具与 Island 可见 | screenshots |
| 失败/恢复 | 无 WebGL 回退没有 JS 异常；context restore 恢复 | browser assertions |
| 首屏体积和加载 | 图片不超过 260 KiB、脚本 gzip 不超过 230 KiB；弱网先出现文字 | CI budget + network profile |
| 集成完整性 | i18n、SEO、JS 语法、git whitespace 通过，导航 HTML hash 不变 | static checks |

测试数据均为页面内置示例，不访问用户文件。结果保存在 `docs/design-previews/race-pets-3d-20261017/`。结束关闭本轮 Chrome 与临时压缩服务器，保留既有 8000 预览。


## 最终结果：通过

通过后对正式文件生成了 `source-sha256.json`。未修改原生 App，未提交、推送或部署；工作位于 `feat/positioning-2.0`，保留本轮前已经存在的官网修改和 scene-pack 工作。

### 造型与动作 review

- 正面、侧面、背面与四个步态分帧检查通过；Pobb 的奶油色脸腹、珊瑚色耳鼻及四枚青色护鳞保留。茄博士的紫色轮廓、眼镜、学士帽、流苏及书保留。
- 修正茄博士面前多余的几何高光；修正迈步与支撑阶段，让脚向前抬、向后蹬；阴影跟随道路倾斜。
- 18 组角色/身体方向/目标组合的眼球世界方向与目标夹角最大约 1.26°。120 个步态采样/角色中，最低支撑点在局部路面上方 0.012–0.021 单位，无穿地或双脚悬空漂移。
- 正式赛道两个角色横向移动范围分别为 `[-3.44, -1.56]`、`[1.56, 3.44]`，身体与视线均随弯道改变。采用沿道路前进的后方追逐视角。

### 交互与生命周期

- 默认自动运行、两轮 `116.193` 秒模拟时间、`1161.93` m、20 次自动投递、10 个目的地全部经过。
- 手动放置翻译图标后，角色真实碰撞并触发 Island；Reduce Motion 下六种工具可直接展示。
- 暂停、离屏、真实后台标签页、Reduce Motion 均冻结时间、角色位置与关节姿态。恢复后继续。
- 390px 默认动态已实测到真实文件碰撞，角色位置与姿态持续变化，目标更新频率为 30；见 `mobile-motion.json`。
- EN/ZH、390px/320px、相机远近切换通过；无横向溢出。320px 短屏保持页面滚动查看工具栏底部。
- WebGL context loss/restore 通过；无 WebGL 时文案、导航和 Island 按钮仍可用；没有页面 JS 异常或 404 请求。
- 普通离开释放模型池和 GPU 资源，诊断中的角色数/几何数归零。没有重新执行真实浏览器 bfcache 后退；该路径沿用前轮验证的事件合同。

### 性能与加载

| 指标 | 实测 |
| --- | --- |
| 角色 mesh / triangle / texture | 43 / 35,214 / 0 |
| 两轮 GPU geometry | 179 → 180，差异来自当前道具 |
| 两轮 GPU texture | 1 → 1 |
| GC 后 JS heap | 6,547,412 → 6,711,720 bytes，增加 160.5 KiB |
| DOM nodes / listeners | 1174 → 1176 / 31 → 31 |
| 首屏图片 | 214 KiB，预算 260 KiB；此前约 699 KiB |
| 全部竞速脚本 gzip | 192 KiB，预算 230 KiB |
| 竞速 atlas 请求 | 0 |
| 慢网 FCP / 场景就绪 | 512 ms / 3641 ms |

慢网条件：冷缓存、gzip 本地服务器、200,000 bytes/s（约 1.6 Mbps）、150 ms 延迟。确认 Three.js 实际使用压缩响应。桌面最多 40 次更新/秒、手机 30 次；canvas 像素上限保持约 160 万。自动化使用隔离 headless Chrome，不以本轮数据保证所有真机 GPU 或 Safari 的帧率。

### 集成检查

`node --check home-race.js`、`node --check home-race-pets.js`、`node scripts/check-home-assets.mjs`、`node scripts/prerender-i18n.mjs --check`、`node scripts/build-seo.mjs --check`、`git diff --check` 均通过。

导航 `<header class="site-nav">` 与接入前逐字一致，SHA-256：`198e5e251bdbeffbe5d0cfb1885350f82704c8d4f7d73f19174ba6f52531d20f`。新增模块覆盖在既有 `/home-race*` 重新验证缓存规则内。

### 测试修正与证据

初轮浏览器脚本在 `/zh/` 点击英文会进入 `/en/`，脚本仍查旧 Island 状态导致断言失败；改为在根路径验证原地语言切换，并分别验证两个语言路由。完整最终重跑通过，最终证据为 `results.json`。首轮模型预览的 robots.txt 页面自动请求 favicon 得到 404，仅存在于隔离造型预览；正式首页网络检查无错误。

证据目录：`docs/design-previews/race-pets-3d-20261017/`：`results.json`、`samples.json`、`model-contract.json`、`compressed-performance.json`、`static-final.json`、`source-sha256.json`，以及造型、步态、竞速、移动端与回退截图。脚本一并保留。

截图保留为压缩 WebP，不参与首页加载。本轮隔离 Chrome 与 8001 压缩测试服务器在完成后关闭；既有 8000 预览保留。
