|
1 | 1 | # v0.22:前端重设计系列(组件体系 / 布局 / 动效 · L0–L6 全层) |
2 | 2 |
|
3 | 3 | > 状态:**实施中** —— 批 0-A(设计系统基座)与批 0-B(图标集)已交付并通过评审;批 0 的其余部分(ADR-033~035 · 豁免表纠偏 · 拆 4 个 >600 行文件 · 原语三层)**待立计划** |
| 4 | +> **2026-09-12 追加(批 2 收口,原文保留不改)**:**批 1(删除批)** 与**批 2(包体治理)**已交付,交付记录见下「交付记录」节(批 1 = 「删除批」节 · 批 2 = 「批 2 · 包体治理」节)。上面那句「批 0 其余部分待立计划」写于 2026-09-11,**批 2 收口时未复核其是否仍成立** —— 批 0-C1(行数治理)/ 0-C2(拆超限文件)/ 0-D(L1 原语层,ADR-033)的落地状态请以规格 §14 的表格与本文件各节记录为准。 |
4 | 5 | > 权威规格:[2026-09-11-frontend-redesign-design.md](../superpowers/specs/2026-09-11-frontend-redesign-design.md)(513 行,本系列的唯一定义源;本文档只做批次归属与交付记录) |
5 | 6 | > 关联:[UX 市场惯例审计](../Foresight/ux-market-convention-audit.md)(本设计的直接输入)· [长期优化清单](../Foresight/long-term-optimization-checklist.md) · [需求池](../product/requirements-pool.md) · [ADR-010](../adr/ADR-010-gap-filling-ai.md)(本系列修订为退役) |
6 | 7 |
|
|
22 | 23 | |---|---|---|---| |
23 | 24 | | **v0.22.0 · 批 0** | 基座:ADR-032~035 + 修订 ADR-010 · 豁免表纠偏 · 拆 4 个超限文件 · token 变量层 · z-index 六档标尺 · 图标集 + 单测 · 原语三层 | 治理 + 基建 | REQ-318 起 | |
24 | 25 | | **v0.22.1 · 批 1** | 删除批(纯减法):21 条命令 + 补缝三连及其连带模块 + 清理死文案 | API 面收敛 | — | |
25 | | -| **v0.22.2 · 批 2** | 包体基线治理:`manualChunks` + 按页动态 import + 量首屏 gzip(现状 651.25 kB gzip / 预算 200 kB) | 性能 | — | |
| 26 | +| **v0.22.2 · 批 2** | 包体基线治理:`manualChunks` + 按页动态 import + 量首屏 gzip(现状 651.25 kB gzip / 预算 200 kB) **✅ 已落(2026-09-12)** | 性能 | — | |
| 27 | + |
| 28 | +> **2026-09-12 批 2 收口更正**:上表 v0.22.2 行的「现状 651.25 kB」是**过期快照** —— 实测开工基线是 **654.72 kB**;交付终态 **92.79 kB(−85.83%)⇒ ✅ 达标**。逐条读数、瓶颈清单与 follow-ups 见「批 2 · 包体治理」节。 |
26 | 29 | | **v0.22.3 · 批 3** | 壳层落地:A′ 顶部 Tab + ⌘K + 溢出两级策略 + 窗口尺寸 + 列注册表 + 断点 + `--nav-h` | 布局 | REQ-318 起 | |
27 | 30 | | **v0.22.4 · 批 4** | 原语迁移进各域:20 弹层 / 44 空态 / 85 加载态 / 196 错误行 / 4 toast / 2 confirm / Button·Surface·Text | 组件体系 | — | |
28 | 31 | | **v0.22.5 · 批 5** | 视图层样板:`viewRegistry` + `ViewSwitcher` + 会话 4 视图 + 笔记 3 视图 + 惰性挂载 + flushSave 守卫 | 展示形式 | REQ-318 起 | |
|
68 | 71 | 7. **47 条未接线命令逐个有结论**,无「不知道」 |
69 | 72 | 8. **标签能写进去**且标签过滤面板有内容;**画面档位选完真的生效**且跨会话记住 |
70 | 73 | 9. JS 包首屏 gzip 达标或给出瓶颈清单;GSAP 只在独立 chunk 懒加载 |
| 74 | + > **进度(批 2 收口,2026-09-12):✅ 达标** —— 首屏 JS gzip **654.72 → 92.79 kB**(预算 `< 200 kB`),守卫 `scripts/check-bundle-budget.mjs` exit 0、余量 107.21 kB。GSAP **未安装**(批 2 硬非目标),但 `vendor-gsap` 独立 chunk 槽位已预留并被单测钉住,批 6 **必须**用 `import()`。⚠️ 达标**不来自** `manualChunks`(它一字节不降首屏),全部来自 `import()`:8 页懒 + 课堂页静态 + 两窗变体 + 对话面板。 |
71 | 75 | 10. 6 个签名动效各自**可中断、可反向**,reduced-motion 下正确降级 |
72 | 76 | 11. `npx tsc --noEmit` 0 错 · `npx vitest run` 全绿 · `cargo test` 全绿(每批) |
73 | 77 |
|
|
135 | 139 |
|
136 | 140 | **未做(登记,逐条带归属)**:`structuredBlocks.ts` 整模块存废 → **批 7**(接线或删除二选一,含 `.ed-low-confidence`)· 25 条「补 UI / 登记不排期 / 撤下 IPC / 有意保留」→ **批 7**(有意保留 3 条无期)· 旧凭据槽 `"default"` 的应用内撤销路径 → **处理 AI 凭据的批次**(产品裁决)· VAD 写端 `publish` 当前 0 测试覆盖 → **批 7 或 VAD 诊断批次(可选)**· `artifact` 行已无任何新建路径(refine 链的正当性只对历史产物行成立)→ **登记,与批 7 的产物判定同批**· `ASR_REQUEST_TIMEOUT` 的删除事实 / 取回方式 / 重引入触发条件 → **登记(无期)**· `commands_video.rs:279` 的 `@param form` 注释与实现不符 → **登记(无期,纯注释)**· REQ-050 / REQ-052 / REQ-053 的功能级陈旧表述 → **产品文档 pass** · **真机 IPC 冒烟整批跳过**(2026-09-11 用户裁决;等价性依据是静态证据链 + 编译期路径解析,**批 3 起如需真机结论必须重新派发,不要沿用「已跳过」**)。 |
137 | 141 |
|
| 142 | +### 批 2 · 包体治理(2026-09-12,实施 `e46e0e82..9921767c`(11 个提交)+ 收口回写 `3f9c64ce`) |
| 143 | + |
| 144 | +**交付**:`app/vite.config.ts` 接线 `manualChunks`(7 个 vendor 族:`editor`/`katex`/`canvas`/`md`/`react`/`tauri` + 为批 6 预留的 `gsap` 槽)· 纯函数 `app/src/build/manualChunks.ts` + 单测 `manualChunks.test.ts`(**本批唯一新增的测试文件**)· 首屏预算守卫 `scripts/check-bundle-budget.mjs`(含 14 条 `--self-test`,口径 = 入口 + 只沿静态 ESM import 可达的 `.js`,gzip `zlib level 6`,十进制 kB)· 首屏静态可达性探针 `scripts/bundle-eager-graph.mjs` · `app/src/App.tsx` 的**模块加载边界重写**(8 个页面按页 `import()` + **首访挂载保活**、两个窗口变体面板按变体懒加载、`AiConversationDock` 首开挂载)· `.gitignore` 取反 `app/src/build/`。**三个非目标全部守住**:不装 GSAP · 不动 `app/src/ui/primitives/**` · 不碰任何 Rust。 |
| 145 | + |
| 146 | +**验收(收口单元 2026-09-12 串行实测,全部 exit 0)**:`check-command-registry` **312/312/0** · `line-limits --full` **`>600` 0 · 301–600 档 123 · 登记条目 123** · `docs-check` exit 0(扫描 273 / 检查 173)· `tsc --noEmit` **0 错** · vitest **125 文件 / 1233 用例** · `cargo test --test app_lib_tests` **2300 passed / 0 failed / 6 ignored** · `cargo clippy --all-targets` **19 条,集合 identical**(**集合比对**,禁止比 sha256)· `check-bundle-budget.mjs`(含真实构建)**exit 0 · 首屏 92.79 kB · 余量 107.21 kB**。 |
| 147 | + |
| 148 | +**账(首屏 gzip 前后对比 + chunk 拓扑)**:首屏 JS gzip **654,722 → 92,789 B = 654.72 → 92.79 kB(−561,933 B = −85.83%)**,预算利用率 **46.39%**;首屏 chunk **1 → 3**(`index` 27.87 + `vendor-react` 60.37 + `vendor-tauri` 4.55 kB);懒 chunk **0 → 22 个 / 574.84 kB**;全部 JS chunk **1 → 25**;首屏可达应用源文件 **251 → 47**、首屏 npm 包 **15 → 4**(`react` / `react-dom` / `@tauri-apps/api` / `plugin-dialog`);构建模块数 **746 不变**。两窗变体首屏 `?float=1` **97.29 kB** · `?overlay=1` **94.19 kB**(均达标)。 |
| 149 | +> **诚实代价(不许省略)**:全部 JS gzip **+12,908 B = +12.91 kB(+1.97%)**(25 chunk 的样板与跨 chunk `import` 开销,**总量守恒不成立**)· `index.html` **+166 B**(两条 `modulepreload`)· CSS gzip **+36 B** · **`>500 kB` 警告仍在**(`vendor-editor` 608,384 B raw / 208.59 kB gzip,整块落在懒 chunk 内)· `dist` 总量只降 **4,415 B(−0.14%)**,59 个 KaTeX 字体 **1,072,948 B 一字节未动** ⇒ **磁盘与安装包不因此变小**(首屏省下的 561.93 kB 是**挪进**懒 chunk,不是消失)。 |
| 150 | +
|
| 151 | +**规格漂移纠正**:§2 包体行 **651.25 → 654.72 kB**(过期快照;「超标 3.26 倍」→ **3.27×**)+ 批 2 终态与诚实代价注 · §10 批 2 行打进度标记并加**口径注**(**`manualChunks` 自身一个字节都不降首屏**;下降全部来自 `import()`,Task 6/7/8 三条缺一不可)+ 收口行 + 瓶颈清单相对链接 · §11 验收 9 加进度注(✅ 达标;GSAP 未装但槽位已预留并被单测钉住)· §13「包体继续膨胀」缓解栏补批 2 已落项与守卫两个待修缺口 · §14 豁免表行(`App.tsx` 439→519,登记值已同步)与交付记录落点行更新。 |
| 152 | + |
| 153 | +**过程中纠正的计划错误(本批最有价值的交付,逐条可复现;全文见批 2 计划就地加注)**: |
| 154 | + |
| 155 | +1. **计划 L1317「窗口变体首屏 = 入口 + 零 vendor」为假** —— 三个窗口**共用同一份 `index.html`**(`WebviewUrl::App("index.html?float=1")`)⇒ 入口静态闭包**逐字节相同**,早返回只能切断**动态**边。实测 = **入口 + 4 个 vendor chunk** ⇒ 变体 **97.29 / 94.19 kB**。连带「变体 < 60 kB」**结构性不可达**(`vendor-react` 单独即 60,367 B > 60 kB)。 |
| 156 | +2. **计划 Task 6 的「9 页 lazy / 0 静态页面 import」经控制方裁决改判为「8 懒 + 课堂页静态」**:课堂是默认页,懒它会让「首屏即被抓取的 20.04 kB」被记作 lazy ⇒ **首屏读数被低估 20.04 kB**。计划 Step 2 预期、Step 3 标题与代码、提交 subject、V1/V2 全部随之过期(实测 V1=**8** / V2=**1**)。 |
| 157 | +3. **计划 Task 6/8 的 Files 清单漏了必须的 `docs/standards/line-limit-exemptions.md` 刷新**(`App.tsx` **439 → 519 行**)。收口时 `node scripts/line-limits.mjs --write` **无 diff**(前序任务已刷新)⇒ 收口提交**不含**该文件(按计划 Step 6 的规则)。 |
| 158 | +4. **计划 Task 10 V4 期望 vitest `124/1124` 不可能成立**:本批净增**恰好一个**测试文件 ⇒ 终态 **125 文件 / 1233 用例**。判据改为「**用例数只增不减 ∧ 0 处断言修改 / 0 处新增 `await` / 0 处改 mock**」(Task 6/7/8 各自前后逐字相同)。 |
| 159 | +5. **计划 Task 9 说「四个候选」实为五个**(`katex` 双版本 · `structuredBlocks` 孤儿 · `@codemirror/lang-markdown` 传递链 · `basicSetup` 附带件 · 59 个 KaTeX 字体),交付是**五行结论表**,**无一条同时过「size-only ∧ behavior-neutral」双闸**。 |
| 160 | +6. **单位漂移(会造出假 Δ)**:计划 §表 1 的「字体 1,047.80 kB」「dist 3,157.49 kB」与 Task 9 候选 5 的 `1,047.80 / 797.64` 都是 **KiB**,十进制是 **1,072.95 / 3,233.27** 与 **1,072.95 / 816.78 kB**。候选 3/4 的 `59.07 / 24.11 kB` 是**分裂前的探针值**(探针总量比真实构建膨胀 +6.3%),落地 A/B 实测为 **−84.04 / −45.10 kB,且 100% 落在懒 chunk 内**。 |
| 161 | +7. **计划 Task 7 Step 5 给的 commit subject 53 字符,超 ≤50 限** —— 交付改用 42 字符的 `perf(app): lazy-load window variant panels`。 |
| 162 | +8. **计划 V3 判据「首屏 gzip 变化 ≤3 kB」被实测 −4.39 kB 突破** ⇒ 控制方改判为「**只许变小 ∧ modules 不变**」(原判据建立在「分块不会改变总量」这一错误假设上)。 |
| 163 | +9. **计划自带的「子串碰撞」反例恒假红**(`@xyflow/react` 的 id 里**没有**连续子串 `node_modules/react`)· **`@types/katex` 覆盖闸必然红**(`dependencies` 实为 **14** 个,计划写 12;已加 1 行惰性登记,根因 F4 登记批 8)。 |
| 164 | +10. **`.gitignore` 的 `build/` 未被锚定 ⇒ 静默吞掉 `app/src/build/`**(Task 3 的两个文件靠 `git add -f` 才入库)。本批只做**点状取反** `!app/src/build/**`,**未动锚定语义**(登记批 8)。 |
| 165 | +11. **Task 1 冻结的 clippy 基线 sha256 不可复现**(基线文件 BOM+CRLF 1724 B vs 抽取器无 BOM+LF 1702 B)⇒ 判据一律改**集合比对**(本批实测集合 19/19 相同、sha256 不同)。 |
| 166 | +12. **「文件不存在」被假报两次**(Task 5 报 `task-3-fix-report.md` 不存在但实际 247 行;Task 9 同类)⇒ 断言「不存在」与断言「0 命中」**同等对待**:说明仪器并自检。 |
| 167 | + |
| 168 | +**本批新增/确认的读数陷阱(累计 13 类,逐条见批 2 计划 Global Constraints 的仪器纪律注)**:含中文的搜索模式经 PowerShell 字符串层被 **GBK 误解码**(给出 0 命中的假阴性)· 无 BOM 的 UTF-8 中文 `.ps1` 被 `-File` 按 GBK 解码(连脚本内 `cmd` 行一起毁)· **整树 ripgrep 遵守 `.gitignore` ⇒ 对被忽略目录整体失明**(同一仪器实测 0 vs 19 命中)· PS 5.1 `>` 重定向写 UTF-16LE · **Tauri 命令名不是唯一 chunk 标记** · **chunk 依赖边是「模块图」的性质、不是「归属表」的性质**(环的根因:只挪模块不挪它自己的依赖闭包)· `git archive` 在未跟踪子目录出 10240 B 空归档 + exit 0 · 解包树里 `git grep` 静默 0 命中 · `Copy-Item` 保留 mtime ⇒ cargo 回放陈旧诊断(还原后先 `touch`)· **A/B Δ 恰为 0 先当仪器故障**、自证仪器能测出已知差异再下结论。 |
| 169 | + |
| 170 | +**未做(登记,逐条带归属)**:路线 A 叶级懒加载(被 B′ 在首屏上完全包含 · 测试面更险)→ **批 5** · 页级错误边界 / 懒 chunk 加载失败重试(`PageSlot` 的 `<Suspense fallback={null}>` 之上只有**全局** `AppErrorBoundary` ⇒ 一次失败卸载整个 `MainShell`、已访问页状态一起丢,**这是本批新增的失败模式**)→ **批 3/4** · 两个窗口变体分支**没有错误边界**(chunk 加载失败 = 空白窗)→ **批 3/4** · 首访加载态 `fallback={null}` → L1 `Loading` 原语 → **批 3/4** · 变体首屏**正式**度量口径(本批只给实测值 + 证明 `< 60 kB` 不可达)→ **批 3** · `structuredBlocks.ts` 整模块存废 + `katex` 版本偏斜(含 `@types/katex`)→ **批 7** · `@codemirror/lang-markdown` 传递链(懒 chunk **−84.04 kB**)+ `basicSetup` 附带件(**−45.10 kB**)两条**耦合**,须一起裁决 → **批 4/5** · 59 个 KaTeX 字体 1,072.95 kB(仅 `.woff2` 可省 816.78 kB)→ **批 8** · 批 6 装 GSAP **必须** `import()` 且核对 `vendor-gsap` 不在首屏(槽位已预留并被单测钉住)→ **批 6** · `check-bundle-budget.mjs` 接线 `.husky/pre-commit` / CI(本批有意不接:它要跑真实构建并写 `app/dist/`)→ **批 8** · 守卫的**嵌套输出路径盲区**(`assets/vendor/*.js` 既不计首屏也不计懒,**仍打印 ✅ 达标 + exit 0**;已用真实构建复现)→ **批 8** · 守卫把「非首屏」一律说成「仅动态可达」的**假文案**(从未验证动态可达性)→ **批 8** · **没有任何门禁看构建日志里的 `Circular chunk`**(环本批已断:1 → **0** 条,但「依赖升级可能让死边复活」⇒ 建议纳入某处判据)→ **批 8** · 两个贴限文件:`scripts/check-bundle-budget.mjs` **299/300**、`app/src/build/manualChunks.test.ts` **292/300** ⇒ **任何新增必须按语义拆分**(守卫拆「口径 / CLI」,测试拆「分组规则 / 反例」)→ **批 8 · 下次改动者当次拆** · `.gitignore` 的 `build/` **锚定语义**未动(本批只点状取反)→ **批 8** · `scripts/**/*.mjs` **不在 `line-limits` 扫描域**(`SOURCE_EXT` 不吃 `.mjs`、`SCAN_DIRS` 只有 `app/src` + `app/src-tauri/src`)⇒ 本批两个新脚本**无门禁保护** → **批 8** · `app/vite.config.ts` **同时**不在 `line-limits` 扫描域**与** `tsc --noEmit` 的 program(`--listFilesOnly` 879 文件 0 命中,正样本 `main.tsx` = 1)→ **批 8** · F4 把 `@types/*` 挪 `devDependencies`(依赖卫生)→ **批 8**。**本批未复核「批 0 其余部分」的落地状态**(本文档「批 0 其余部分(未落地)」节写于 2026-09-11)→ **批 8** 复核。 |
| 171 | + |
| 172 | +**瓶颈清单指针**:本批的瓶颈清单(14 行,每行含实测 gzip / 为什么降不下去 / **具名归属批次** / 复现命令)在批 2 计划 [2026-09-11-frontend-redesign-batch2-bundle.md](../superpowers/plans/2026-09-11-frontend-redesign-batch2-bundle.md) 的 **§收口回写**节,另有 **Task 12 收口终态**节(终态六门禁表 + 回写落点表 + 追加 follow-ups 15–18)。规格 §10 明写「后一批的细节依赖批 0–2 的实测结果(**尤其是包体治理量出的瓶颈清单**)」⇒ **批 3 的计划者请先读该清单**。 |
| 173 | + |
138 | 174 | ### 批 0 其余部分(未落地) |
139 | 175 |
|
140 | 176 | 规格 §10 的批 0 还包含:**ADR-033~035**(当前 `docs/adr/` 最高为 ADR-032)· 豁免表纠偏 · 拆 4 个 >600 行文件 · 原语三层。**这些不在 0-A / 0-B 范围内**,后续子批次另行立计划。 |
|
0 commit comments