[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。
參考資料
- How React server components work: an in-depth guide @ plasmic
- RFC: React Server Components @ reactjs/rfcs