angular universal app performance, APP_BOOTSTRAP_L

2020-03-27 06:38发布

问题:

Angular 4.4.6
Angular CLI 1.3.2
Node 6.x.x
NPM 3.10.10
Webpack 3.4.1

In Angular Universal application when server view sift to client view there is flicker of screen, because all the API's which were called in server side rendering, also called in client side rendering, due to there was a flicker.

To remove this flicker I implemented Angular Universal Transfer Module, it stores data in a Map cache (private _map = new Map<string, any>();) while in server side rendering, and transfers it to client so client does not need to call the api again and imediately have the data from cache.

And the transfer was through this provider.

{
    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();
        });
    };
}

This way the flicker has gone, but application performace has decreased, on load testing the app, the flickered result is more faster than non-flickered app, why is that ?

May be because in case of load testing or in case of bots hitting the website there is no browser so the cache never get cleared and it just fill the server with cache memory and server gets slow, what could be the solution for that, either create different instace for bots and real user, by identifying request at nginx level, oe there is some other thing I'm missing in angular universal.

回答1:

Edit: this solution is for angular 5

When I had the flickering problem I just added BrowserTransferStateModule to the client app

//app.module.ts
import {BrowserModule, BrowserTransferStateModule} from '@angular/platform-browser';
imports: [
//...
BrowserModule.withServerTransition({appId: 'my-app'}),
BrowserTransferStateModule,

then ServerTransferStateModule to the server app

//app.server.module.ts
import {ServerModule, ServerTransferStateModule} from '@angular/platform-server';

//...
 imports: [
AppModule,
ServerModule,
ServerTransferStateModule

And I modified main.ts to boostrap the app once the dom is loaded

//main.ts
document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
});

I did not use APP_BOOTSTRAP_LISTENER like you did (not sure if it makes a difference)