Angular Hydration

什麼是 SSR ?

SSR 的全名是 Server-Side Rendering,是一種網頁開發技術。它指的是在 server 端將網頁應用程式的原始碼轉換成 HTML 字串,然後將這些 HTML 發送到 client 端。當 client 端收到預先渲染的 HTML 時,它可以立即在瀏覽器上顯示,而無需等待 JavaScript 加載和執行。這樣可以提高網站的首次加載速度,改善搜尋引擎的索引效果,以及提供更好的使用者體驗。

什麼是 Hydration ?

Hydration 是指 client 端將 server 端回傳的 HTML 字串轉換成具有 Angular 功能的實時應用。在這個過程中,Angular 會將預先渲染的 HTML 中的靜態內容與 Angular 的動態功能結合起來,並綁定事件,讓使用者可以直接操作 app,就像與 client 端渲染的應用進行交互一樣。

v16 的 Hydration 亮點是什麼?

舊版的 Hydration 過程是透過 server 端渲染畫面之後送到 client 端,client 端雖然可以快速的看到應用程式的第一個畫面,但實際上還是要整個 App 在 Client 端重新渲染一次,因為 client 端無法訪問 Angular app 的狀態,這樣的過程會影響到使用體驗而且不夠有效率。

新的 Angular hydration 通過允許 client 端訪問 Angular app 狀態來解決這個問題。這意味著 client 端不必在 server 端呈現 HTML 後重新渲染整個應用。相反,client 端可以直接混合應用程式狀態,這是一個更快的過程。

如何使用 SSR ?

啟用 SSR 有幾個步驟:

  1. 確認是否有升級到 Angular v16:
npx ng update
npx ng update @angular/core @angular/cli
  1. 加入 @nguniversal/express-engine,會出現詢問是否執行自動執行,選擇 Yes:
ng add @nguniversal/express-engine

完成之後會產生四個檔案,並更新 package.json:

CREATE src/main.server.ts
CREATE src/app/app.config.server.ts
CREATE tsconfig.server.json
CREATE server.ts
  1. 建立一個 app.config.ts,並將 main.ts 中的 bootstrapApplication 第二個參數(options) 搬過來:
    由於 app.config.server.ts 會引用 app.config.ts,但目前沒有建立,所以我們要手動新增,例如:
import { ApplicationConfig, importProvidersFrom, isDevMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ServiceWorkerModule } from '@angular/service-worker';

export const appConfig: ApplicationConfig = {
  providers: [
    importProvidersFrom(
      BrowserModule,
      ServiceWorkerModule.register('ngsw-worker.js', {
        enabled: !isDevMode(),
        // Register the ServiceWorker as soon as the application is stable
        // or after 30 seconds (whichever comes first).
        registrationStrategy: 'registerWhenStable:30000',
      })
    ),
  ],
};
  1. 並把 main.tsoptions 改成 import 的方式:
import { bootstrapApplication } from '@angular/platform-browser';

import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
  1. 執行 npm run dev:ssr,以自己做的 TODOMVC 的跑分結果。
    沒有 SSR 的分數:
    Result
    使用 SSR 的分數:
    Result

SSR 的優點

  • 更快的首頁渲染時間:由於伺服器已經渲染了初始 HTML,客戶端可以立即顯示內容,而無需等待 JavaScript 加載和執行。
  • 搜索引擎優化 (SEO): SSR 使搜索引擎更容易抓取和索引 app 的內容,因為它們可以直接讀取伺服器發送的 HTML。
  • 提高可訪問性:部分瀏覽器可能對於 JavaScript 支持有限, SSR 可以確保這些瀏覽器至少能看到基本的內容和功能。

SSR 可能的挑戰及問題

在實現 Angular SSR 時,可能會遇到一些需要探討的問題:

  • 性能問題:在 server 上渲染 app 會增加 server 的負擔,對於高流量的網站,這可能會導致性能問題。
  • client 端和 server 之間的狀態同步:由於 SSR 需要在 client 端和 server 之間共享狀態,開發人員需要確保兩者之間的狀態同步,以防止出現錯誤或不一致的行為。
  • 環境差異:由於 client 端和 server 環境的差異,開發人員需要確保應用的程式碼可以在這兩個環境中正常運行。這可能涉及到檢查和處理某些特定於環境的 API 和功能。
  • 增加複雜性:引入 SSR 可能會增加應用的複雜性,因為開發人員需要依照情況維護和管理兩個不同環境的程式碼。這可能需要更多的開發和測試時間。

參考資料

Server-side rendering with Angular Universal
Angular Hydration
Angular v16 is here!
Server Side Rendering (SSR) in Angular v16
All About Server-side Rendering w/Angular v16