跳至主要内容

[note] React Server Component

React Server Component 基本概念

作用(How)

React Server Component (RSC) 能夠讓 React 的元件部分在 server 被 rendered、部分在 client 被 rendered。

解決了什麼(Why)

透過 RSC 試圖讓 React 元件能在 server 或 client 得到最好的發揮,有些元件適合在 client 被 render(例如,使用者互動)、有些則時候在 server 被 render(例如,存取資料),並不是所有 React 元件都需要在 client 端 render,透過這樣的分工以提升頁面載入的速度、較小的 bundle size 和更好的 UX:

  • 較快的 data fetching

    • 改善 waterfall 式的 data fetching 所導致的效能問題外
    • 在 server 端取得資料(例如,向 database、API 取得資料)通常速度會比較快
  • 減少 bundle size:許多 npm packages 不必要讓 client 都下載,減少不必要的 bundle size,加快 bundle files 下載的速度,舉例來說,markdown parser、chart graph 這類的套件可以在 server 端統一先把 UI 處理好再傳給 client,不需要讓���個 user 都下載一大包的 bundle files。

RSC vs. SSR

SSR 回傳的是先被 server render 好的「HTML」檔,client 收到 HTML 後還需要去下載 JavaScript 並執行 hydrate 的動作;而 Server Component 實際上不是 render 成 HTML,而是 render 成一種特殊的格式(format),這讓 React Server Component 可以只更新該元件,使用者在畫面上的其他元件和資料狀態都可以被保存不必重新載入(這也是一開始 CSR 的最大好處)。

事實上,RSC 和 SSR 是相輔相成的(complementary)。

筆記:Introducing Zero-Bundle-Size React Server Components

Introducing Zero-Bundle-Size React Server Components @ React

Server Component 想要解決的問題

如果我們設計「每個 component 只去 fetch 自己需要的資料」,而不是在上層的 parent component 把資料拿完後才開始 render child component,如此:

  • 會有比較好的程式維護性:每個元件都只管理自己所需要的資料,不需要多拿其他元件所需的
  • 效能會較差:因為父層拿完資料後,子層才開始 render 並去拿資料(也就是所謂的 waterfall)

在 Facebook 可以透過 GraphQL 和 Relay 來解決上面的問題,各個 component 只拿自己所需的資料,但發 request 的時候,則會把所需的資料一次拿齊。

但處理透過 GraphQL 來解決這個問題之外,另一個方式是把 Component 從 Client 搬到 Server

在 Server 把所有的資料都拿齊全後才回給 Client。

資訊

邏輯上從 server 端 fetch 資料會比從 client 端快的多。

透過 Server Component 解決了:

  • waterfall 式的 fetching data 導致的效能問題外;
  • 較小的 bundle size:在 server component 中的程式碼(包含第三方套件)並不會被 bundle 進 client-side JavaScript 中,這也有效降低了 client-side JavaScript 檔案的大小,進一步對效能有所提升

Server Component 的特色

  • Automatic client code splitting:自動將在 client component 做 code-splitting
  • Zero effect on bundle size:Sever Component 只會在 server 被執行,所有的程式碼不會傳到 client,因此可以減少 client-side JavaScript 的 bundle sizes
  • Access the backend directly:Server Component 可以直接存取使用 server 的功能,例如存取資料庫、讀取檔案等等
  • Server Component 實際上不是 render 成 HTML,而是 render 成一種特殊的格式(format),這使的 Sever Component 可以在保持 Client-side 資料狀態的同時進行更新,
  • 開發者可以決定元件的優先級,選擇那些元件在 render 時要較早被載入

如何使用 Server Component

Server Component 的檔案名稱會是 xxx.server.js,表示這個元件只會在 server 端被 render,它的程式碼並不會被傳送到 client;而原本在 React 中的元件則會命名為 xxx.client.js,表示這個元件只會在 client 端被 render;如果該元件的命名是 xxx.js,則表示這是在 server 或 client 都可以被使用的 shared component。

  • 在 Server Component 中能夠載入 Client Component,並且用 props 的方式將資料從 Server Component 傳進 Client Component(但有一個前提是,這些資料必須要是可被序列化的資料)。
  • 在 Client Component 中不能載入 Server Component。
提示

一個便捷的想法是,透過 server component 拿資料,再將資料以 props 的方式傳給 client component。

參考資料