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 启动,如果不小心会重新启动)
- 持续应用状态
是否可以避免破坏 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 启动,如果不小心会重新启动)
- 持续应用状态