angular 通用销毁模块引用

angular universal destroy moduleref

是否可以避免破坏 moduleRef 并将其重新用于下一个请求(比如在浏览器中工作)?应用程序花费太多时间来重新填充存储(API-请求)所以我发现有可能缓存它。

这是来自ngx-universal/express-engine

的源代码
function handleModuleRef(moduleRef: NgModuleRef<{}>, callback: Function, req, res) {
    const state = moduleRef.injector.get(PlatformState);
    const appRef = moduleRef.injector.get(ApplicationRef);

    appRef.tick();
    appRef.isStable
        .filter((isStable: boolean) => isStable)
        .first()
        .subscribe((stable) => {
            const bootstrap = moduleRef.instance['ngOnBootstrap'];
            bootstrap && bootstrap();

            if (!res || !res.finished) callback(null, state.renderToString());
            moduleRef.destroy(); // remove this line and avoid creating new instance of NgModuleRef every request
        });
}

调试帮助我理解它是如何工作的,我实现了这样的代码:

function handleModuleRef(moduleRef: NgModuleRef<{}>, callback: Function, req, res) {
    const state = moduleRef.injector.get(PlatformState);
    const appRef = moduleRef.injector.get(ApplicationRef);
    const router = appRef.components[0].instance.router;
    const zone = appRef.components[0].instance.zone;
    zone.run(() => {
        router.navigateByUrl(req.originalUrl);
    });
    appRef.isStable
        .filter((isStable: boolean) => isStable)
        .first()
        .subscribe((stable) => {
            const bootstrap = moduleRef.instance['ngOnBootstrap'];
            bootstrap && bootstrap();

            if (!res || !res.finished) callback(null, state.renderToString());
        });
}

我们需要在 bootstrapped

的主要组件中注入 Router 和 NgZone

当我们进入 "handleModuleRef" 时,我们需要通过将新导航 url 推送到路由器来破坏 (isStable=false) 应用程序以启动 "changeDetector"。但是如果你知道 "isStable" 是一个 属性 区域(每个应用程序一个)并且技巧是在 "zone.run(...)" 中调用 "router.navigateByUrl" 来破坏区域稳定。 1)应用处理新路由 2) 区域自身不稳定 3)等到稳定(区域内没有任务) 4)渲染 5) 盈利!

结果:

  • 通过在内存中缓存所有应用程序并避免每个请求 bootstrap
  • ,渲染速度提高了 2-3-4 倍
  • 可能存在内存泄漏(应用程序在 docker 启动,如果不小心会重新启动)
  • 持续应用状态