[Next.js] What is Rendering in Next.js?
Next.js 是一個基於 React 的 SSR 解決方案
Next.js 有兩種 pre-rendering 方式
- Server-side Rendering
- Static-site Generation (Recommended)
Server-side Rendering (服務器端渲染)
針對每個請求動態產生 HTML 頁面, 因為服務器端渲染導致性能比靜態生成慢,所以只有在絕對必要時才使用它。

每次客戶端請求頁面時,服務器將獲取該頁面的數據(call api), 並使用該數據生成頁面的 HTML(render 畫面)。 只有完成所有這些操作後,HTML 才會發送回客戶端。
優點
- 伺服器端渲染不需關心瀏覽器兼容的問題
- 可解決 SEO 問題
缺點
- 每次的重新 Render 會造成後端的負擔提升也讓使用者的體驗變差
- Server 端渲染的頁面看上去似乎可以交互,但實際上還是要等待 js 執行完成才能交互。簡單地說,會增加 TTI(Time to Interactive)
Static-site Generation (Recommended)
在編譯的時候,並將在每個請求上重用 HTML。
將生成 HTML 頁面的工作放到編譯時,而不必在請求帶來時動態完成。 為每個 URL 預先單獨生成 HTML 文件,達到極佳的 FCP 效能。

實際操作
- 使用 next export: 將所有頁面導出到可以與任何主機一起使用的靜態 HTML 文件
- 用 nginx 做反向代理: 針對 out folder 啟動 next server
要怎麼選擇使用 Server-side Rendering 或是 Static Generation
部落格,官網,電子商務產品列表...等靜態頁面 => 使用 Static Generation
兩者都能解決 SEO 問題

此圖參考網址:https://zhuanlan.zhihu.com/p/113853235
bonus : csr vs. ssr vs. Static Rendering 👈
參考: https://developers.google.com/web/updates/2019/02/rendering-on-the-web
Client-Side Rendering (CSR)
在前端進行 Render,後端作為資料供應的 API 層。 當需要新的資料時,前端發送 Request 後只需要部份更新畫面就好。
渲染流程:
- 客戶端發起頁面請求,服務端把頁面(響應的字符串)發送給 Client 端
- Client 端從上到下依次解析,解析過程中,發現網絡請求,再次向服務器發送網絡請求,Client 端拿到響應的結果,render 出 HTML 頁面。

優點:
- 靈活,真正的前後端分離,方便於前後台各自更新維護。
缺點:
- 有些 CSR 的網站會造成爬蟲取得的頁面不是那麼完整,造成 SEO 的問題。
- 第一次載入畫面是等到前端載入後,會有一段時間的空白。
Server-side Rendering
Server 端完全可以在獲取到 HTML 文件的內容之後經過一些處理再返回給 Client 端,也就說,Server 端可以將數據插入到 HTML 字符串中之後再返回給 Client 端
渲染流程:
在後端接收到 Request 即產生 HTML 畫面給前端,
伺服器每次收到請求時在產生對應的靜態頁面
簡單來說 client 不用下載大量的 javascript, 因為 HTML 渲染整個是在 Server 端完成在將 HTML 傳至 client 端的瀏覽器顯示。
每當有 client 發起對某個頁面的 request 時,server 會抓取對應的資料,建立完整的 HTML,最後再回傳給 client,不需要先下載一堆 JS 和 CSS 後才能看到頁面(FCP 加載速度快),即使因為 JS 還沒被執行,所以畫面還不具備互動性,但讓使用者先看到畫面,再利用人的感知延遲時間去執行 JS code,可以大大減少使用者的跳出率

優點:
- SEO。
- 不需要先下載一堆 JS 和 CSS 後才能看到頁面(FCP 加載速度快)。
缺點:
- 因渲染在 Server 端,這樣的作法不論點擊什麼網頁上什麼功能,每一次都是將整個畫面重新繪製,如果在頻寬網路較差的情況下,會是一個較不好的體驗,因為要一直重新 loading 整個頁面
Static-site Rendering
需要為每個 URL 單獨生成一份 HTML 文件, 靜態頁面是在 build-time 時就產生,伺服器收到 request 時重複使用這些已經生成好的靜態頁面。
渲染流程: server 每次收到 request 是都是回傳「相同的」、「一開始就產生好的」 HTML 檔給 client。

筆記
- SSR 和 CSR 的最大差異是使用者最終 UI 上看到的 HTML DOM 元素是由 server 產生(SSR)、 或是由 client(CSR)所產生
- SSR 和 SSG 最大的差異是在 HTML 檔案被建立、產生的時間點。SSR 會在每次收到 request 時才產生對應的 HTML,因此每次回傳 client 的 HTML 對 server 來說都是獨立不同的;但 SSG 是在一開始就把所有需要用到的頁面都建立出來,在收到 request 時就直接用相同、一開始就產生好的 HTML 回傳回去。
參考文件
- https://nextjs.org/docs/basic-features/pages#static-generation-recommended
- http://www.ayqy.net/blog/csr-vs-ssr-vs-prerendering-vs-hydration/
- https://yxyuxuan.github.io/2019/09/18/SSR%E5%92%8CCSR/
- https://pjchender.dev/react/nextjs-getting-started/
- https://hackmd.io/@spyua/HJDJUaTSO
- https://oldmo860617.medium.com/%E5%BE%9E-next-js-13-%E8%AA%8D%E8%AD%98-react-server-components-37c2bad96d90