Skip to content

fix(next-ui): 修复内嵌子应用分页切回时卡死在加载遮罩及黑屏问题 - #233

Merged
lioensky merged 1 commit into
lioensky:mainfrom
infinite-vector:fix/embedded-app-tab-switch-reload
Oct 6, 2026
Merged

lioensky merged 1 commit into
lioensky:mainfrom
infinite-vector:fix/embedded-app-tab-switch-reload

Conversation

@infinite-vector

Copy link
Copy Markdown
Contributor

动机与背景

在 Next UI 架构中,通过左上角「+」组件库以内嵌标签页形式打开子应用(如工程施工台、主题等基于 WebContentsView 的内嵌分页)后,当用户在 VChat 主对话与子应用分页之间往复切换时,存在概率性卡死在带有旋转图标的“正在打开应用…”遮罩上,或切回后呈现空白/黑屏的缺陷。

排查确认该问题存在三重并发根因:

  1. 遮罩未清理与 CSS 契约缺失:内嵌视图容器在创建时注入了 loading 遮罩,在底层应用就绪变为 data-state="ready" 后,该 DOM 节点未被清理,且 CSS 缺少强隐藏规则;
  2. 切走切回引发的 0 尺寸定界污染:标签切走时容器变为 hidden(display: none),切回瞬间若在重排完成前抓取 getBoundingClientRect() 会得到 0,旧逻辑兜底为 1px 并通过 IPC 写入主进程,将会话视口破坏性压缩为 1x1 像素;
  3. Chromium 原生视图重绘停摆(DelegatedFrameHost 特性):WebContentsView 在 setVisible(false) 隐藏后合成帧暂停,单纯重新执行 setVisible(true) 时若未重新排布置顶或唤醒 GPU,视图可能处于未刷新状态,从而透出底盘的旋转加载动画。

解决方案与架构设计

建立三层防御与自愈闭环:

  1. 主进程会话层(embeddedAppSessionManager.js):
    • 会话创建时赋予合法的默认窗口边界与 insets,避免初始 1x1;
    • 在 setBounds 中增设最小有效边界保护网(width/height <= 1 时安全忽略),杜绝异常 0 尺寸污染健康会话;
    • 在 activate 时,依据 insets 紧贴当前主窗口边界自适应对齐最新视口;同时在 contentView 中重新置顶原生视图,并调用 invalidate() 强制激活 Chromium 合成管线。
  2. 渲染层状态机守卫(next-shell-controller.js):
    • 容器进入 ready 状态后,立即从 DOM 树中移除 .next-ui-embedded-app-status 状态节点;
    • syncEmbeddedActivation 异步回调严格校验当前活动的 activeViewId,杜绝切标签过快时的陈旧回调串扰;并在下一帧安全对齐真实排版尺寸。
  3. 样式层强约束兜底(ui-next.css):
    • 补齐强样式契约:html .next-ui-embedded-app-view[data-state="ready"] .next-ui-embedded-app-status { display: none !important; }。

测试与验证

  • 运行全套相关单元测试(app-tab-host.test.js、embedded-app-controller.test.js、embedded-app-security.test.js、overlay-coordinator.test.js、launchpad-controller.test.js、creation-controller.test.js 共 29 项),全部 100% PASS;
  • 运行官方标签页全生命周期回归脚本(test-next-ui-tab-lifecycle.mjs),无错误通过;
  • 本地真实界面环境下,在工程、主题及对话之间进行高频快速往复切换,应用保持丝滑秒开与实时自适应,未再复现卡加载或黑屏现象。

……
嗯?怎么ai给我塞了个!important……算了就一个。

@infinite-vector
infinite-vector force-pushed the fix/embedded-app-tab-switch-reload branch from 78704dc to 0e85b2d Compare October 6, 2026 10:26
@lioensky
lioensky merged commit 5bea478 into lioensky:main Oct 6, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants