Forráskód Böngészése

Merge remote-tracking branch 'origin/perf-base-v1' into perf-base-v1

86132 1 hete
szülő
commit
7e8f32ba47
2 módosított fájl, 16 hozzáadás és 23 törlés
  1. 7 13
      src/qiankun/index.ts
  2. 9 10
      改动说明-fix-subapp-loading.md

+ 7 - 13
src/qiankun/index.ts

@@ -35,21 +35,15 @@ const mountMicroApp = (name, isReFresh = false) => {
   }
 };
 
-// 卸载app的方法
 const unmountMicroApps = async (multipleApp) => {
-  // [fix-subapp-loading] 修复卸载竞态:原实现用 multipleApp.filter(async (name) => { await …unmount() })
-  // —— async 回调使 filter 立即返回、await 不被任何方等待,卸载是"发射后不管";
-  // 且判断条件 multipleApp.some 是函数引用(恒真)。改为顺序 await 逐个卸载,完成后清理注册表,
-  // 避免旧实例与新实例并存争抢容器/共享状态(子应用切页互清场景)。
   if (!multipleApp || multipleApp.length === 0) return;
-  for (const key of Object.keys(activeApps)) {
-    if (multipleApp.some((name) => name.includes(key))) {
-      try {
-        await activeApps[key].unmount();
-      } catch (e) {
-        console.error('[fix-subapp-loading] 微应用卸载失败:', key, e);
-      }
-      delete activeApps[key];
+  if (JSON.stringify(activeApps) !== '{}' && multipleApp.some) {
+    for (const key in activeApps) {
+      multipleApp.filter(async (name) => {
+        if (name.includes(key)) {
+          await activeApps[key].unmount();
+        }
+      });
     }
   }
 };

+ 9 - 10
改动说明-fix-subapp-loading.md

@@ -1,8 +1,6 @@
 # 改动说明: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。
+> 日期:2026-09-10 | 分支:`fix-subapp-loading`(基于 master `b5a6721d`)| 范围:**仅 mky-vent-base** 依据:docs/17 §8 实测("风量监测"新开标签页永久加载)、docs/16 基座审核 #6、docs/15。原则:小步修改,不改业务逻辑与子应用通信协议;每处带 `[fix-subapp-loading]` 注释;可单项 revert。
 
 ## 背景一句话
 
@@ -13,16 +11,17 @@
 ### 第 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 仍未见容器内容基本可判定子应用挂载失败。超时放行后的表现:页面可见、三维区可能空白(用户可刷新重试),远好于无限转圈。参数可按现场调整(调大调小只改默认值)。
+**为什么是 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` 注册表。
 
@@ -30,11 +29,11 @@
 
 ## 预期效果
 
-| 场景 | 改前 | 改后 |
-|---|---|---|
-| 子应用挂载失败/停摆 | 整页"正在加载"永久转圈 | 最多 60s 后放行页面(附 console.error 定位信息) |
-| 门户在两个子应用宿主路由间切换 | 旧实例卸载与新挂载竞态,实例泄漏/争抢 | 卸载完成后再挂载,注册表干净 |
-| 子应用正常挂载 | 正常 | 正常(无行为变化) |
+| 场景                           | 改前                                  | 改后                                             |
+| ------------------------------ | ------------------------------------- | ------------------------------------------------ |
+| 子应用挂载失败/停摆            | 整页"正在加载"永久转圈                | 最多 60s 后放行页面(附 console.error 定位信息) |
+| 门户在两个子应用宿主路由间切换 | 旧实例卸载与新挂载竞态,实例泄漏/争抢 | 卸载完成后再挂载,注册表干净                     |
+| 子应用正常挂载                 | 正常                                  | 正常(无行为变化)                               |
 
 ## 风险与回退