Angular SSR,页面重新渲染问题

时间:2020-04-13 13:23:00

标签: javascript angular server-side-rendering angular-universal

我是Angular ssr的新手,您可以在下面查看代码

问题

如果我直接输入客户路由,则会先显示

由服务器呈现

但很快便重新显示页面并显示:

由浏览器呈现

我想我知道为什么会发生这种情况,但是可以肯定有人可以提供很好的解释吗?另外,我可以以某种方式避免这种行为并强制浏览器呈现来自服务器的html吗?我应该为此担心吗?

client.component.ts

@Component({
  selector: "client",
  template: "<p>Rendered by {{ renderer }}</p>",
  styleUrls: ["./dumco.component.css"]
})
export class ClientComponent implements OnInit {

  renderer: string;
  bla: any = [];

  constructor(private http: HttpClient, @Inject(PLATFORM_ID) platformId: any) {
    this.renderer = isPlatformBrowser(platformId) ? "Browser" : "Server";
  }
}

app-routing.module.ts

import { NgModule } from "@angular/core";
import { RouterModule, PreloadAllModules } from "@angular/router";
import { AppComponent } from "./app.component";
import { CompfComponent } from "./compf/compf.component"
import { HomeComponent } from "./home/home.component"

export const appRoutes = [
  {
    path: "",
    component: HomeComponent
  },
  {
    path: "comp",
    component: CompfComponent
  },
  {
    path: "client",
    loadChildren: () => import("./client/client.module").then(m => m.ClientModule),
    data: { title: "Static Data - Clients" }
  },
];

// preloadingStrategy: PreloadAllModules,
@NgModule({
  imports: [RouterModule.forRoot(appRoutes, { onSameUrlNavigation: "reload", initialNavigation: 'enabled' })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from "@angular/common/http";

import { AppRoutingModule } from "./app-routing.module"

import { AppComponent } from './app.component';
import { CompfComponent } from './compf/compf.component';
import { HomeComponent } from './home/home.component';

import { TransferHttpCacheModule } from "@nguniversal/common"

@NgModule({
  declarations: [
    AppComponent,
    CompfComponent,
    HomeComponent
  ],
  imports: [
    HttpClientModule,
    TransferHttpCacheModule,
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    AppModule,
    ServerModule,
    ServerTransferStateModule
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

1 个答案:

答案 0 :(得分:1)

这是角度通用的正常行为。这是正常的流程:

  1. 您向服务器发出请求
  2. Angular Universal在服务器端创建并呈现组件(包括API调用)以生成HTML内容。内容将发送回客户端浏览器。 (在您的示例中,HTML将包含“由服务器呈现”)
  3. 浏览器呈现HTML。
  4. 一旦呈现页面并加载dom文档,客户端的角度应用程序就会得到增强。
  5. 客户端角度应用程序创建和渲染组件(并进行API调用)。它将根据您的情况呈现“由浏览器呈现”。

您真的不必为此担心。在实际情况下,您将让组件进行API调用。为了防止客户端进行与服务器端相同的调用,可以使用angular TransferState在HTML生成的服务器端序列化API数据,以便客户端可以直接使用该数据。再次进行API调用。

这样,客户端生成的HTML应该与来自服务器的HTML相同。 (当然,除非您像示例中那样专门显示不同的数据服务器和客户端)