Spartacus SSR fallback 成 CSR 时,仍然会在后端继续保持渲染,这个行为在 optimized-ssr-engine.ts
的下列注释里看的很清楚:
actual rendering task
仍然会在后台
继续进行,最终渲染的 SSR response 会存储在 cache 里。
假设 Angular 应用的 home page 完成 SSR 渲染,需要花费 3 秒。
考虑下列的场景:
- 页面请求 A 进来,正在进行服务器端渲染。
- 第二个请求 B 2 秒之后进来,请求同样的页面。因为页面请求 A 已经触发了一个正在运行的服务器端渲染,并且还剩1秒才能完成,所以请求 B 会被 CSR 处理。
- 三秒之后,出于某种原因,请求 A 没有办法被 SSR 响应,因此 CSR 再次发生。请求 A 也得到了 CSR 响应。然后 SSR 仍然在后台继续进行。
- 假设 7 秒之后,请求 A 触发的 SSR task 终于完成了。这个 SSR response 存储在 Spartacus SSR 的 memory cache 里。
- 假设 10 秒之后,请求 C 请求同样的 url,会从 SSR memory cache 里立即得到 SSR 响应。
Angular 是一个流行的前端框架,Angular Universal 则是 Angular 提供的一个用于实现服务器端渲染(Server-Side Rendering,SSR)的解决方案。在理解 Angular Universal engine 进行服务器端渲染时的后台渲染之前,让我们先了解一下什么是服务器端渲染。
服务器端渲染是一种将页面的渲染过程从客户端移动到服务器端的技术。在传统的客户端渲染(Client-Side Rendering,CSR)中,浏览器加载页面的 HTML 文件,然后使用 JavaScript 在客户端渲染页面内容。而服务器端渲染是在服务器上预先生成页面的 HTML,并将其发送到客户端,客户端仅需要负责显示页面而不需要执行大量的渲染操作。
Angular Universal engine 是 Angular 团队提供的一个框架,用于在服务器上运行 Angular 应用,并支持服务器端渲染。通过 Angular Universal,可以实现在服务器端生成动态的 HTML,并将其发送到客户端,从而提高页面加载性能和搜索引擎优化。
后台渲染是服务器端渲染的一种表现形式,意味着渲染过程在服务器后台完成。在 Angular 中,后台渲染可以通过 Angular Universal engine 来实现。Angular Universal 的主要目标之一是使开发者能够在同一套代码中运行 Angular 应用的服务器端和客户端部分。
让我们通过一个例子来说明后台渲染的过程。考虑一个简单的 Angular 组件:
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: '<h1>{{ message }}</h1>', }) export class AppComponent { message = 'Hello, Server-Side Rendering!'; }
在客户端渲染中,这个组件的渲染过程将在浏览器中进行。但是,如果我们启用 Angular Universal,并使用服务器端渲染,这个组件将在服务器上进行渲染,然后将生成的 HTML 发送到客户端。这就是后台渲染的基本概念。
配置 Angular Universal 需要一些额外的步骤,包括设置服务器入口、调整应用程序模块等。在这里,我们简要说明一下这些步骤:
- 安装 Angular Universal 模块:
ng add @nguniversal/express-engine
- 创建服务器端入口文件:
// server.ts import 'zone.js/dist/zone-node'; import * as express from 'express'; import { ngExpressEngine } from '@nguniversal/express-engine'; import { AppServerModule } from './src/main.server'; const app = express(); const PORT = process.env.PORT || 4000; app.engine( 'html', ngExpressEngine({ bootstrap: AppServerModule, }) ); app.set('view engine', 'html'); app.set('views', 'dist/browser'); app.get('*.*', express.static('dist/browser', { maxAge: '1y' })); app.get('*', (req, res) => { res.render('index', { req }); }); app.listen(PORT, () => { console.log(`Server listening on http://localhost:${PORT}`); });
- 调整应用程序模块:
// app.server.module.ts import { NgModule } from '@angular/core'; import { ServerModule, ServerTransferStateModule } from '@angular/platform-server'; import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader'; import { AppComponent } from './app.component'; import { AppModule } from './app.module'; import { AppRoutingModule } from './app-routing.module'; @NgModule({ imports: [ AppModule, ServerModule, ServerTransferStateModule, ModuleMapLoaderModule, AppRoutingModule, ], bootstrap: [AppComponent], }) export class AppServerModule {}
通过这些步骤,我们启用了服务器端渲染,并且 Angular 应用将能够在服务器端和客户端之间共享相同的代码和状态。
总的来说,后台渲染是通过 Angular Universal engine 在服务器端执行 Angular 应用的渲染过程,将生成的 HTML 发送到客户端,以提高性能和搜索引擎可索引性。这是一种强大的技术,特别是对于需要更好性能和更好搜索引擎优化的应用程序。