[P1][CR-F8] 生成的 meta 文件全量静态导入:act-scene chunk 约 3.3MB,生产环境开启 sourcemap #532

Open
opened 2026-09-29 06:43:59 +00:00 by troytt · 0 comments
Owner

来源:#516|优先级 P1|评审编号 F8|基线 e475c2e

问题描述

三个由打包脚本生成的 TypeScript 元数据文件合计约 8 万行,全部被静态 import 进主入口。vite 配置里也没有 manualChunks,结果 act-scene 的 chunk 达到约 3.3MB(gzip 后约 730kB)。生产构建还开着 sourcemap: true,map 文件有 10.6MB,并且会随站点一起公开发布。

另外,生成器在模板字符串里输出运行时逻辑,这部分代码没法单独测试。

证据

文件 行数 生成器
src/render/missiles-meta.ts 17,751 scripts/pack-missiles.ts
src/render/overlays-meta.ts 23,834 scripts/pack-overlays.ts
src/ui/baked-ui-meta.ts 38,199 scripts/pack-ui.ts
  • sourcemap:vite.config.ts:22 设置了 sourcemap: true。
  • 没有拆包:rollupOptions 里只配置了多入口,没有 manualChunks。上面三个文件都被静态 import,所以会进入首屏 chunk。
  • 生成器输出运行时逻辑:velocityToDccDirection 写在生成器的模板字符串里(pack-missiles.ts:547),生成后出现在 missiles-meta.ts:76。它是渲染时每帧都要调用的函数,却无法在不运行生成器的情况下单独测试或修改。
  • 缺少防手改标记:三个文件的头注释写了 "Auto-generated by …",但没有 "DO NOT EDIT" 标记,也没有校验生成物与脚本输出是否一致,手动改动很容易在下次重新生成时被覆盖。

以上构建数据来自在 e475c2e 上执行 vite build 的结果。

根因

  • 元数据按"TS 常量"的形式生成,天然就会被静态 import 进 bundle。
  • 打包配置一直沿用默认设置,没有针对体积做过优化。

修复指南

  1. 元数据改为 JSON,并按需懒加载:
    • 生成器输出 public/.../*.json,或者 src/ 下的 .json 文件(配合 import() 实现代码分割);
    • 运行时按 act 或场景 fetch / 动态 import():进入 Act 1 只加载 Act 1 用到的投射物、overlay 和 UI 元数据;
    • 类型定义保留在一个小的手写 .ts 文件中,JSON 通过运行时校验(至少校验版本号和字段存在性)后再使用。
  2. 运行时逻辑移到普通模块:velocityToDccDirection 这类函数移到 src/render/missile-direction.ts,生成器只输出数据,并为这类函数补上单元测试。
  3. sourcemap 改为 'hidden':仍然生成 map 用于错误上报还原,但不在产物中引用、不公开发布。如果确实需要公开,也要单独决定并记录原因。
  4. 拆包:用 manualChunks 把 drlg、技能数据、UI 元数据拆成独立的 chunk,并用 rollup-plugin-visualizer 这类工具生成报告,放进 CI 产物里。
  5. 生成物标记与校验:
    • 生成文件的头部加上 // DO NOT EDIT — generated by scripts/pack-xxx.ts;
    • CI 中重新运行生成器并与仓库里的版本 diff,不一致就失败。
  6. 路径可移植:生成脚本中的开发者家目录硬编码问题见 #536。

验收标准

  • 生产构建中,首屏 chunk(act-scene 及其同步依赖)小于 1MB(gzip 前),并在本 issue 中附上构建报告截图或数据。
  • 生产产物中没有 //# sourceMappingURL 引用,也不发布 .map 文件。
  • velocityToDccDirection 位于普通模块中并有单元测试;三个生成文件只包含数据。
  • CI 中有"重新生成并 diff"的检查。
  • 涉及渲染,按惯例跑一遍全部 136 个关卡的无头审计,确认懒加载后画面无回归。
  • npm run typecheck 0 error;npx vitest run 全部通过。

相关

  • #505(首屏性能):相关但不重叠。#505 覆盖 embedded-drop-tables 和 .r8,本 issue 覆盖这三个 meta 文件和 sourcemap。
  • #530:投射物图集清单与打包对齐。
  • #536:脚本中的硬编码路径。
  • #538:public/ 中烘焙资源入库的问题。
> 来源:#516|优先级 P1|评审编号 F8|基线 `e475c2e` ## 问题描述 三个由打包脚本生成的 TypeScript 元数据文件合计约 8 万行,全部被静态 import 进主入口。vite 配置里也没有 `manualChunks`,结果 act-scene 的 chunk 达到约 3.3MB(gzip 后约 730kB)。生产构建还开着 `sourcemap: true`,map 文件有 10.6MB,并且会随站点一起公开发布。 另外,生成器在模板字符串里输出运行时逻辑,这部分代码没法单独测试。 ## 证据 | 文件 | 行数 | 生成器 | |---|---|---| | `src/render/missiles-meta.ts` | 17,751 | `scripts/pack-missiles.ts` | | `src/render/overlays-meta.ts` | 23,834 | `scripts/pack-overlays.ts` | | `src/ui/baked-ui-meta.ts` | 38,199 | `scripts/pack-ui.ts` | - **sourcemap**:[vite.config.ts:22](https://git.projectdiablo2.cn/troytt/diablo2-web/src/commit/e475c2e6d8a6e85eabb607525d9d87beca9fbee3/vite.config.ts#L22) 设置了 `sourcemap: true`。 - **没有拆包**:`rollupOptions` 里只配置了多入口,没有 `manualChunks`。上面三个文件都被静态 import,所以会进入首屏 chunk。 - **生成器输出运行时逻辑**:`velocityToDccDirection` 写在生成器的模板字符串里([pack-missiles.ts:547](https://git.projectdiablo2.cn/troytt/diablo2-web/src/commit/e475c2e6d8a6e85eabb607525d9d87beca9fbee3/scripts/pack-missiles.ts#L547)),生成后出现在 [missiles-meta.ts:76](https://git.projectdiablo2.cn/troytt/diablo2-web/src/commit/e475c2e6d8a6e85eabb607525d9d87beca9fbee3/src/render/missiles-meta.ts#L76)。它是渲染时每帧都要调用的函数,却无法在不运行生成器的情况下单独测试或修改。 - **缺少防手改标记**:三个文件的头注释写了 "Auto-generated by …",但没有 "DO NOT EDIT" 标记,也没有校验生成物与脚本输出是否一致,手动改动很容易在下次重新生成时被覆盖。 以上构建数据来自在 `e475c2e` 上执行 `vite build` 的结果。 ## 根因 - 元数据按"TS 常量"的形式生成,天然就会被静态 import 进 bundle。 - 打包配置一直沿用默认设置,没有针对体积做过优化。 ## 修复指南 1. **元数据改为 JSON,并按需懒加载**: - 生成器输出 `public/.../*.json`,或者 `src/` 下的 `.json` 文件(配合 `import()` 实现代码分割); - 运行时按 act 或场景 `fetch` / 动态 `import()`:进入 Act 1 只加载 Act 1 用到的投射物、overlay 和 UI 元数据; - 类型定义保留在一个小的手写 `.ts` 文件中,JSON 通过运行时校验(至少校验版本号和字段存在性)后再使用。 2. **运行时逻辑移到普通模块**:`velocityToDccDirection` 这类函数移到 `src/render/missile-direction.ts`,生成器只输出数据,并为这类函数补上单元测试。 3. **sourcemap 改为 `'hidden'`**:仍然生成 map 用于错误上报还原,但不在产物中引用、不公开发布。如果确实需要公开,也要单独决定并记录原因。 4. **拆包**:用 `manualChunks` 把 drlg、技能数据、UI 元数据拆成独立的 chunk,并用 `rollup-plugin-visualizer` 这类工具生成报告,放进 CI 产物里。 5. **生成物标记与校验**: - 生成文件的头部加上 `// DO NOT EDIT — generated by scripts/pack-xxx.ts`; - CI 中重新运行生成器并与仓库里的版本 diff,不一致就失败。 6. **路径可移植**:生成脚本中的开发者家目录硬编码问题见 #536。 ## 验收标准 - [ ] 生产构建中,首屏 chunk(act-scene 及其同步依赖)小于 1MB(gzip 前),并在本 issue 中附上构建报告截图或数据。 - [ ] 生产产物中没有 `//# sourceMappingURL` 引用,也不发布 `.map` 文件。 - [ ] `velocityToDccDirection` 位于普通模块中并有单元测试;三个生成文件只包含数据。 - [ ] CI 中有"重新生成并 diff"的检查。 - [ ] 涉及渲染,按惯例跑一遍全部 136 个关卡的无头审计,确认懒加载后画面无回归。 - [ ] `npm run typecheck` 0 error;`npx vitest run` 全部通过。 ## 相关 - #505(首屏性能):相关但不重叠。#505 覆盖 `embedded-drop-tables` 和 `.r8`,本 issue 覆盖这三个 meta 文件和 sourcemap。 - #530:投射物图集清单与打包对齐。 - #536:脚本中的硬编码路径。 - #538:`public/` 中烘焙资源入库的问题。
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#532
No description provided.