We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在 qiankun 场景下,多个子应用切换时到会导致 window.addEventListener(popstate) 无法移除,导致内存溢出。
qiankun
window.addEventListener(popstate)
主要原因是:umi 通过 createHistory 生成路由时(history.tpl),history 模式会执行 createBrowserHistory ,而 createBrowserHistory 未接受传入的 opts,导致 history 在初始化路由时,window 值取了默认值 document.defaultView(createBrowserHistory)。
umi
createHistory
history
createBrowserHistory
opts
window
document.defaultView
这种情况在 qiankun 场景下,createBrowserHistory 获取 document.defaultView 时触发沙箱逃逸(qiankun 内部主子应用会共享 document),实际取值为主应用的 window 对象,从而导致多个子应用的监听都会订阅到主应用上,即使子应用卸载后,事件监听还会存在,来回切换子应用时会不停的在主应用上累计监听,导致子应用会内存泄漏。
umi 临时文件 .umi/core/history.ts:
.umi/core/history.ts
export function createHistory(opts: any) { let h; if (opts.type === 'hash') { h = createHashHistory(); } else if (opts.type === 'memory') { h = createMemoryHistory(opts); } else { // 期望透传 opts 给 history 的 createBrowserHistory h = createBrowserHistory(); } if (opts.basename) { basename = opts.basename; } // ... return h; }
history 的 createBrowserHistory 源码:
// remix-run/history export function createBrowserHistory( options: BrowserHistoryOptions = {} ): BrowserHistory { let { window = document.defaultView! } = options; let globalHistory = window.history; // ... window.addEventListener(PopStateEventType, handlePop); // ... }
期望解法:createBrowserHistory 可以接收 opts 参数,让用户传递子应用代理后的 window 参数(qiankun 内部会对 addEventListener 打补丁,可以保证子应用卸载时移除事件订阅)。
addEventListener
The text was updated successfully, but these errors were encountered:
可以估计多少次切换子应用后会导致页面崩溃吗,因为内存泄漏很容易在各种代码里发生,在一定程度上是可以容许泄露的,但这确实是一个问题。
Sorry, something went wrong.
页面崩溃的case比较难测,除了history的监听泄漏,qiankun 沙箱还存在其他场景下的泄漏比如:深度对象的代理修改会触发沙箱逃逸,也会存在一定的内存泄漏。 目前 history 的问题主要是因为 createBrowserHistory 时没有接收 opts 参数,不知道是否可以支持用户手动传入的参数,比如: window。
我认为如果此问题不解决,最多只是一定程度的内存泄漏,但并没有人发生应用的崩溃,因为很多应用都存在内存泄露,在一定程度是允许的,所以这个问题不是致命的。
关键代码位置:
umi/packages/preset-umi/templates/history.tpl
Line 9 in 88416e9
Line 13 in 88416e9
@sorrycc 看 blame 是你,还能想起来原因吗
No branches or pull requests
What happens?
在
qiankun
场景下,多个子应用切换时到会导致window.addEventListener(popstate)
无法移除,导致内存溢出。主要原因是:
umi
通过createHistory
生成路由时(history.tpl),history
模式会执行createBrowserHistory
,而createBrowserHistory
未接受传入的opts
,导致history
在初始化路由时,window
值取了默认值document.defaultView
(createBrowserHistory)。这种情况在
qiankun
场景下,createBrowserHistory
获取document.defaultView
时触发沙箱逃逸(qiankun 内部主子应用会共享 document),实际取值为主应用的window
对象,从而导致多个子应用的监听都会订阅到主应用上,即使子应用卸载后,事件监听还会存在,来回切换子应用时会不停的在主应用上累计监听,导致子应用会内存泄漏。umi
临时文件.umi/core/history.ts
:history
的createBrowserHistory
源码:期望解法:
createBrowserHistory
可以接收opts
参数,让用户传递子应用代理后的window
参数(qiankun 内部会对addEventListener
打补丁,可以保证子应用卸载时移除事件订阅)。Context
The text was updated successfully, but these errors were encountered: