Angular 4.4.6
Angular CLI 1.3.2
Node 6.x.x
NPM 3.10.10
Webpack 3.4.1
在Angular Universal应用程序中,当服务器视图筛选到客户端视图时,屏幕闪烁,因为所有在服务器端渲染中调用的API,也称为客户端渲染,因为存在闪烁。
为了消除这种闪烁,我实现了Angular Universal Transfer Module,它在服务器端渲染时将数据存储在Map缓存(private _map = new Map<string, any>();
)中,并将其传输到客户端,因此客户端不需要再次调用api,而是需要从缓存中获取数据。
转移是通过这个提供商。
{
provide: APP_BOOTSTRAP_LISTENER,
useFactory: onBootstrap,
multi: true,
deps: [
ApplicationRef,
TransferState
]
}
export function onBootstrap(appRef: ApplicationRef, transferState: TransferState) {
return () => {
appRef.isStable
.filter(stable => stable)
.first()
.subscribe(() => {
transferState.inject();
});
};
}
这种方式闪烁已经消失,但应用程序性能下降,在对应用程序进行负载测试时,闪烁的结果比非闪烁的应用程序更快,为什么呢?
可能是因为在负载测试的情况下或者在机器人点击网站的情况下没有浏览器,因此缓存永远不会被清除,它只是填满服务器的缓存内存和服务器变慢,可能是解决方案,或者创建通过在nginx级别识别请求,机器人和真实用户的不同实例,oe还有一些我在角度通用中缺失的东西。
编辑:此解决方案适用于角度5
当我遇到闪烁问题时,我刚刚将BrowserTransferStateModule添加到客户端应用程序中
//app.module.ts
import {BrowserModule, BrowserTransferStateModule} from '@angular/platform-browser';
imports: [
//...
BrowserModule.withServerTransition({appId: 'my-app'}),
BrowserTransferStateModule,
然后ServerTransferStateModule到服务器应用程序
//app.server.module.ts
import {ServerModule, ServerTransferStateModule} from '@angular/platform-server';
//...
imports: [
AppModule,
ServerModule,
ServerTransferStateModule
我修改了main.ts,以便在加载dom后引导应用程序
//main.ts
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
});
我没有像你那样使用APP_BOOTSTRAP_LISTENER(不确定它是否有所作为)