🧠 了解 Angular 20 中的服务器端渲染(SSR):SSR vs CSR vs 预渲染

欢迎观看本视频!
Angular 20 刚刚发布,今天我们将探讨一个社区用户强烈要求的主题:服务器端渲染(SSR)Hydration(水合/激活),以及这些概念在 Angular 中是如何实现的。
我特别喜欢 Angular 中的 增量 Hydration(Incremental Hydration),我们将在稍后详细讲解。
这将是多部分系列的第一集,我们将从头开始了解什么是 SSR,并通过创建一个新的启用 SSR 的 Angular 应用程序来实践。


Bookmark This Article

Your browser doesn't support automatic bookmarking. You can:

  1. Press Ctrl+D (or Command+D on Mac) to bookmark this page
  2. Or drag this link to your bookmarks bar:
Bookmark This

Clicking this bookmarklet when on any page of our site will bookmark the current page.

🤔 什么是服务器端渲染(SSR)?

当我们谈论 服务器端渲染(SSR) 时,本质上是指我们在服务器端按需生成完整的 HTML 内容。

💡 这里的关键词是“按需”——这意味着每当用户访问某个特定路由时,服务器都会执行一次完整的渲染过程,并将已生成的 HTML 返回给浏览器。

这会在服务器上增加一些负载,因为每个用户请求相同的路由时都会触发一次完整的渲染流程。因此,SSR 特别适合用于动态内容,例如你需要从数据库中获取数据,然后将其渲染到页面上并发送给客户端。

✅ SSR 的优势:

  • 更快的内容首次绘制(FCP):用户能更快看到有意义的内容。
  • 更好的 SEO 支持:搜索引擎可以轻松地抓取服务器返回的完整 HTML。
  • 可预测的数据获取流程:API 调用或数据库查询可以直接在服务器端完成。
  • 避免空白页或加载动画闪烁:无需等待 JavaScript 执行即可展示内容。

🔁 CSR 与 SSR:根据场景选择

使用 客户端渲染(CSR) 时,服务器只会返回最小的 HTML 结构(即“壳”)以及 JavaScript 包。JavaScript 包会解析这个壳,并在浏览器端运行 Angular 编译器来生成组件和 HTML 内容。

CSR 在后续导航中表现优异。一旦页面加载完成,用户可以在不同路由之间快速切换,而无需重新向服务器请求整个页面。这使得用户体验非常流畅。

SSR 的优势在于首次加载:用户第一次访问时就能看到已经渲染好的内容,从而显著改善 首次内容绘制(FCP)最大内容绘制(LCP)


⚙️ 使用 Angular CLI 创建支持 SSR 的项目

要创建一个默认启用 SSR 的 Angular 项目,请运行以下命令:

ng new ngv20-demo-app --ssr

选择 CSS 作为样式语言,并暂时关闭 Zoneless 模式

该命令将自动配置好 Express.js 支持 SSR 所需的所有文件: - src/main.server.ts - src/server.ts - src/app.routes.ts

创建完成后,构建并运行应用:

ng build
npm run serve:ssr

你的应用将会运行在 http://localhost:4000


📂 Angular SSR 项目的结构

dist/ 文件夹中,你会看到两个子文件夹: - browser/:包含静态资源(HTML、JS、CSS) - server/:包含服务端打包后的文件(如 main.js, server.mjs 等)

server.ts 文件负责配置 Express 服务器,并使用 @angular/ssr/node 包在服务端渲染 Angular 应用。


🧪 测试不同的渲染模式

Angular 20 允许你在 app.routes.ts 中轻松配置渲染模式。选项包括: - 'client':仅客户端渲染 - 'server':每次请求都由服务器渲染 - 'prerender':构建时预渲染静态 HTML

示例代码:

{
  path: '',
  component: AppComponent,
  data: { renderMode: 'server' }
}

AppComponent 中添加日志

为了观察初始化发生在哪一端,你可以在 AppComponent 中添加如下代码:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  ngOnInit() {
    console.log('App initialized');
  }
}

🔍 查看页面源码验证渲染方式

使用浏览器的 “查看页面源码(View Page Source) 功能来判断 HTML 是否来自服务器。

CSR 模式 下:

  • 页面源码只显示基本的 HTML 壳(如 <app-root>)。
  • 所有内容都是在 JavaScript 加载后由客户端生成的。

SSR 模式 下:

  • 页面源码中可以看到完整的 HTML 内容。
  • 每次刷新页面时,终端都会输出 App initialized 日志。

预渲染模式(Prerender) 下:

  • 页面源码同样显示完整 HTML。
  • 但日志仅在构建时出现一次(ng build 时),而不是在每次请求时。

🛠️ Angular v20 中的增量 Hydration

Angular v20 引入了 增量 Hydration,这是一个重要的新特性。

🔍 Angular v20 注意事项: 增量 Hydration 允许你逐步激活页面中的组件,而不是一次性激活整个应用。这样可以提升首屏交互速度,同时保留 SSR 的优点。


🎯 如何选择 SSR、CSR 或预渲染?

| 使用场景 | 推荐模式 | |----------|-----------| | 动态页面(博客、产品详情、用户资料) | SSR | | 内部仪表盘或工具 | CSR | | 静态页面(隐私政策、FAQ) | 预渲染 | | 高流量网站 | CSR 或预渲染(减少服务器压力) |


📘 下一步计划:Defer Blocks 与懒加载

在本系列的下一期中,我们将介绍 Angular 中的新特性 Defer Blocks(延迟块),这是一个非常强大的功能,可以让你只在需要时才加载某些组件。
我们会看看它是如何与 SSR 协同工作的,以及它如何帮助你减少初始加载时间。


💬 总结

理解 Angular 中不同的渲染策略,可以帮助你做出更明智的技术决策,尤其是在性能、SEO 和用户体验方面。

随着 Angular v20 的发布,SSR 变得更加易用。如果你的应用面向公众并且对 SEO 有较高要求,没有理由不去使用 SSR。

敬请期待本系列的后续内容!