📜  角度服务器端渲染 - Javascript (1)

📅  最后修改于: 2023-12-03 15:27:55.454000             🧑  作者: Mango

角度服务器端渲染 - Javascript

简介

在传统的 Web 开发中,浏览器向服务器请求数据并接收 HTML 页面进行渲染。这种方式被称为客户端渲染。然而,客户端渲染的性能问题和 SEO 不友好,因为搜索引擎爬虫无法识别由 JavaScript 生成的内容。为了解决这些问题,服务端渲染(SSR)出现了。

Angular 是基于 TypeScript 和 JavaScript 的前端框架,与 React、Vue 和 Ember 等框架一样。Angular 官方支持在服务器端进行 SSR 以提高性能和搜索引擎可见性。

优点

SSR 的优点主要是:

  • 更快的首次渲染时间,因为 HTML 和 CSS 在服务器上预编译并在响应中发送,用户不必等待浏览器下载、编译 JavaScript 和请求数据;
  • 更好的 SEO。由于搜索引擎爬虫无法识别 JavaScript,SSR 可以让搜索引擎抓取完整的 HTML 页面并索引它们;
  • 更好的可访问性。因为 HTML 和 CSS 在服务器上预编译,所以用户代理可以选择不启用 JavaScript,从而达到更好的可访问性;
  • 更好的性能。SSR 会减少浏览器需要处理的工作量,并能为瘦客户端(Thin Client)构建打下坚实的基础。
如何实现

Angular 官方提供了一些优秀的工具来构建和部署 SSR 应用程序。有两种方法可供选择:

  • 客户端等待,也称为 Angular Universal,它在服务器上渲染了应用程序并将 HTML 发送回客户端,客户端将 HTML 渲染。
  • 服务器向客户端推送,也称为 Angular Prerendering,它在编译时渲染了应用程序的部分,并将它们与静态 HTML 一起部署。

下面是一个简单的示例代码:

<!--index.html-->
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <base href="/">
  <title>Angular App</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="styles.3ff695c00d717f2d2c04.css">
</head>

<body>
  <app-root></app-root>
  <script src="runtime-es2015.858f6e3e3d659dd6e9c9.js" type="module"></script>
  <script src="runtime-es5.858f6e3e3d659dd6e9c9.js" nomodule defer></script>
  <script src="polyfills-es5.24f074290988c4129742.js" nomodule defer></script>
  <script src="polyfills-es2015.ff146f6b1ec78af38fb3.js" type="module"></script>
  <script src="main-es2015.0d7a0f2cedafb2f1d764.js" type="module"></script>
  <script src="main-es5.0d7a0f2cedafb2f1d764.js" nomodule defer></script>
</body>

</html>
<!--main.server.ts-->
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import * as express from 'express';
import * as fs from 'fs';
import { join } from 'path';

const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');

const app = express();

const router = express.Router();

router.get('/*', (req, res) => {
  res.render('index', { req, res });
});

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

app.use(express.static(join(DIST_FOLDER, 'browser')));

app.use('/', router);

app.listen(PORT, () => {
  console.log(`listening on http://localhost:${PORT}!`);
});

以上是使用 Angular Universal 的方法。我们可以使用 @nguniversal/express-engine (相当于 Angular 的模板编译引擎)将服务器端渲染应用程序的责任委派给 Express,并使用 provideModuleMap (相当于创建并提供一个模块映射)将相关的 NgModule 输入映射传递给 Angular 的服务器端渲染引擎。

客户端等待的方式在处理“添加到购物车”和“清除购物车”等用户交互性操作时可实现较好的性能,而服务器向客户端推送的方式则通常适用于内容稳定且每个用户看到的内容都一样的页面。选择哪种方式取决于你的应用程序的性质和需求。

结论

在这篇文章中,我们介绍了 Angular 服务器端渲染的优点、如何实现以及两种常见的实现方式。希望这些内容能够帮助你更好地理解服务器端渲染概念和使用 Angular 实现服务器端渲染的方法。