Browse Source

docs: 改动说明-fix-subapp-loading.md(逐项位置/原因/风险/回退)

86132 4 ngày trước cách đây
mục cha
commit
3a86e311c6
1 tập tin đã thay đổi với 47 bổ sung0 xóa
  1. 47 0
      改动说明-fix-subapp-loading.md

+ 47 - 0
改动说明-fix-subapp-loading.md

@@ -0,0 +1,47 @@
+# 改动说明:fix-subapp-loading(基座微应用挂载健壮性修复)
+
+> 日期:2026-09-10 | 分支:`fix-subapp-loading`(基于 master `b5a6721d`)| 范围:**仅 mky-vent-base**
+> 依据:docs/17 §8 实测("风量监测"新开标签页永久加载)、docs/16 基座审核 #6、docs/15。
+> 原则:小步修改,不改业务逻辑与子应用通信协议;每处带 `[fix-subapp-loading]` 注释;可单项 revert。
+
+## 背景一句话
+
+用户典型路径(首页点"风量监测"→新开标签页)出现**永久"正在加载"**:基座的两层加载遮罩(启动屏 + ventModal 挂载遮罩)的收起条件完全依赖"三维子应用就绪",而生产所部署的子应用构建存在绘制链停摆缺陷 → 遮罩永挂、整页不可用。本分支让基座在该场景下**超时放行**,并修复子应用卸载竞态。
+
+## 改动明细(6 文件,2 组提交)
+
+### 第 1 组:挂载遮罩超时兜底 + 就绪等待防中断
+
+| 文件 | 改动 |
+|---|---|
+| `src/utils/domUtils.ts` | `resetMicroContentWH(domId, callBack, maxWaitMs = 60000)`:新增 `maxWaitMs` 参数(默认 60s,向后兼容)。原实现每秒无限轮询等待 `#容器` 出现首个子节点——微应用挂载失败时容器永远为空,遮罩永久转圈。现超时后强制执行 `callBack()`(隐藏遮罩、放行页面)并停止轮询(原实现还有轮询本身永不停止的小泄漏)。超时时输出 `console.error` 便于定位。 |
+| `src/components/vent/micro/ventModal.vue`(3D 容器) | `onMounted` 中 `mountMicroApp(...)` 包 `try`,`resetMicroContentWH(...)` 移入 `finally`——若 mount 同步抛错,就绪等待仍然启动,遮罩不会因"抛错跳过收起逻辑"而永久卡死。 |
+| `ventModal2D.vue` / `needAir.vue` / `ventDoc.vue` | 同款 try/finally(分别对应 2D / 需风量 / 内业三个子应用容器)。 |
+
+**为什么是 60 秒**:正常暖缓存挂载 ≤10s(实测 8.6~10.6s),冷缓存 40~60s;60s 仍未见容器内容基本可判定子应用挂载失败。超时放行后的表现:页面可见、三维区可能空白(用户可刷新重试),远好于无限转圈。参数可按现场调整(调大调小只改默认值)。
+
+### 第 2 组:`src/qiankun/index.ts` 卸载竞态修复
+
+`unmountMicroApps` 原实现两个 bug:
+1. `multipleApp.filter(async (name) => { await …unmount() })` —— `filter` 的 async 回调使 `await` 不被任何方等待,**卸载是"发射后不管"**;调用方 `onBeforeUnmount(async () => { await unmountMicroApps(...) })` 以为在等,实际拿到的是 filter 的新数组(立即返回)。旧实例的卸载与新实例的挂载并发竞争容器。
+2. 判断条件 `multipleApp.some` 是**函数引用**(恒真),属笔误;且卸载后不清理 `activeApps` 注册表。
+
+修复:改为 `for…of Object.keys(activeApps)` 顺序 `await` 卸载,`try/catch` 单个失败不阻断其余,卸载成功后 `delete activeApps[key]`;入参空数组直接返回。匹配语义保持原样(`name.includes(key)`)。
+
+## 预期效果
+
+| 场景 | 改前 | 改后 |
+|---|---|---|
+| 子应用挂载失败/停摆 | 整页"正在加载"永久转圈 | 最多 60s 后放行页面(附 console.error 定位信息) |
+| 门户在两个子应用宿主路由间切换 | 旧实例卸载与新挂载竞态,实例泄漏/争抢 | 卸载完成后再挂载,注册表干净 |
+| 子应用正常挂载 | 正常 | 正常(无行为变化) |
+
+## 风险与回退
+
+- 本分支未改子应用通信协议、路由结构、任何业务页面;最坏情况是"超时放行后三维区空白"(与改前"永久转圈"相比是改善)。
+- 回退:`git revert` 对应 commit 即可,两组改动相互独立。
+- **未做构建验证**:本机无该仓库 node_modules(pnpm 工程,依赖未安装)。改动均为小范围 TS/Vue 模板级修改,已逐行自查;请审核者本地 `pnpm install && pnpm build` 验证后再合并。
+
+## 与 VentModelWeb 修复分支的关系
+
+VentModelWeb 侧的修复分支 `perf-load-v5`(Gogs 同服务 msx/VentModelWeb)解决三维子应用自身的切页重建/泄漏/绘制停摆;**本分支不替代它,二者建议都合**——本分支是基座侧的防御性兜底:即使未来子应用再出挂载问题,门户也不会整页永久卡死。