iT邦幫忙

2023 iThome 鐵人賽

DAY 3
2
Modern Web

深入淺出,完整認識 Next.js 13 !系列 第 3

Day 03 - 什麼是網頁渲染 ( Rendering )?CSR、SSR、SSG、ISR 有什麼差別?

  • 分享至 

  • xImage
  •  

昨天提到 Next.js 的特色之一,是頁面渲染方式預設為 Pre-Rendering。那到底 Pre-Rendering 是什麼呢?優缺點是什麼呢?今天就來好好認識一下 Client Side Rendering ( CSR )、Server Side Rendering ( SSR )、Static Side Generation ( SSG )、Incremental Static Regeneration (ISR) 四種網頁渲染方式吧!


在開始介紹前,先來回答幾個你可能有的疑惑:

  • Pre-Rendering 等於 SSG?
    你可能在網路上看到有些文章將 Pre-Rendering 與 SSG 畫上等號,但我們會以 Next.js 官方對於 Pre-Rendering 的定義為準,即 HTML 於 server 端產生,因此 SSR、SSG、ISR 均屬於 Pre-Rendering。

  • 一直聽到渲染 ( Rendering ) 這個詞,渲染到底是什麼意思呢?
    假如你 Google 這個詞,你可能會看到 3D 渲染、物理學、電腦繪圖等等各式不同解釋,提及網頁渲染時,Next.js 官方給了一個簡單明瞭的答案:

There is an unavoidable unit of work to convert the code you write in React into the HTML representation of your UI. This process is called rendering.

簡單來說就是將你寫的程式碼轉成 HTML,而依照渲染發生的時機與地點,可分成 SSR、SSG、CSR、ISR 四種常見的網頁渲染模式。

解決這些疑惑後,我們接著來比較四者的差異和各自的優缺點:

Client Side Rendering ( CSR ):

當使用者進入網頁,web server 收到 client 的請求後,會回傳一個幾乎是空的 HTML 檔案 (ex: <body> 中只有 <div id="root"> ),以及一份用來建造 UI 的 JavaScript,由瀏覽器透過 JavaScript 操控 DOM 來完成渲染工作。

瀏覽器收到 response 後,將會進行 parsing、layout、paint、composite 等流程,將畫面根據指示呈現給使用者,假如有興趣了解細節,可搜尋 Browser Rendering 等關鍵字。
https://ithelp.ithome.com.tw/upload/images/20230903/20161853Wky0dluj4A.png
( 圖片來源:https://nextjs.org/learn/foundations/how-nextjs-works/rendering )

優點:
切換頁面不用重新向 server 發 request,並等 server 生成頁面 html,頁面載入速度較快,切換頁面時使用體驗會較 SSR 網頁順暢。

缺點:

  1. 首次載入速度較慢,因為頁面內容要等到 JavaScript bundle 下載完後才會開始渲染,在網速慢或低階裝置的環境下會尤其明顯。
  2. 對搜尋引擎爬蟲較不友善,SEO 較差。

Server Side Rendering ( SSR ):

web server 每次收到 client 請求,會產生一份完整的 HTML 文件,回覆給瀏覽器來呈現靜態畫面

問題來了,假如我的網頁包含動態元素呢 ( ex: 點擊按鈕觸發內容改變 )?事實上 server 回傳給瀏覽器的內容除了 HTML 文件以外,還包含了一份 JSON 和 JavaScript 文件,用來告訴瀏覽器該如何將各 DOM element 轉為動態,以及他們對應的 state 的初始值。瀏覽器即可依照指示將對應的 DOM element 加上事件監聽器,並賦予初始值,這個過程稱為 Hydration。
https://ithelp.ithome.com.tw/upload/images/20230903/20161853cJwPkilSxN.png
( 圖片來源:https://nextjs.org/learn/foundations/how-nextjs-works/rendering )

優點:

  1. 因不需要等瀏覽器下載完 JavaScript bundle 即可生成頁面,用戶可較快開始與網頁互動。

  2. 頁面內容會在 search engines 爬蟲前生成,有利 SEO。
    補充:Google 和 Bing 爬蟲引擎現在可以索引 “Synchronous" 的 JS App。但假如頁面內容是透過 AJAX 取得,爬蟲不會等非同步事件處理完才爬。細節之後的文章也會跟大家分享

  3. 假如頁面含有串接 API 內容,在 server 端 fetch 資料庫 data 速度會相較在 client 端快。

缺點:

  1. Server 需額外資源來處理 Rendering,會增加負荷,當流量大時,或有很慢的 API 時,可能會影響網頁讀取速度。
  2. 每次切換頁面,都需要等待 server 渲染 HTML後回傳給 client,使用者等待頁面 loading 時間會較久,使用者體驗較差。
  3. Server 環境不支援的功能 ( ex: window, local storage API ) 無法使用,後續介紹 Server Component 時會詳細說明。

Static Side Generation ( SSG ):

靜態 HTML 文件一樣在 Server 端產生,但不同於 SSR,HTML 是在 build time 時產生,生成後會存在 CDN 中,web server 收到瀏覽器請求時,會重複使用已經生成好的 HTML。

https://ithelp.ithome.com.tw/upload/images/20230903/201618536IzZh0uncC.png
https://ithelp.ithome.com.tw/upload/images/20230903/201618537BgjmfxlZf.png
( 圖片來源:https://nextjs.org/learn/basics/data-fetching/two-forms )

優點:
因 HTML 於 build-time 生成,對 server 負擔較小,網頁載入速度較快,也可避免一些安全漏洞。

缺點:
因為 HTML 於 build-time 即生成,所以難以支援動態內容,也不適合需要經常更新內容的網頁 (ex: 每一頁的 HTML 都不一樣 )。

Incremental Static Regneration (ISR)

那假如想做 Pre-Rendering,有沒有辦法同時享受 SSG 的效能,和 SSR 的靈活性呢? 於是 Vercel 在 Next.js 9 時 ( 可參考公告 ) 提了一個新的 solution:Incremental Static Regneration (ISR)。

簡單來說,部分的頁面可以在 build time 渲染。當 server 收到 request 發現沒有對應的靜態頁面時,就會跑SSR,並將頁面渲染的結果存快取,假如之後有相同的 request 就可以直接從快取拿。開發者也可以頁面為單位,設定每個頁面重新渲染 ( revalidate ) 的時間,當 server 收到 request 且過了 revalidate 的時間時,會先回給 client cached 版本,並重新渲染頁面。


怕篇幅太長,今天的內容就先到這邊!明天再和大家分享幾個查看網站是 Pre-Rendering 還是 CSR 的方法,接著就會正式開始介紹 Next.js 13!

謝謝大家耐心的閱讀,我們明天見!


上一篇
Day 02 - 認識 Next.js,什麼是全端框架?
下一篇
Day 04 - 該怎麼知道網站是 CSR 還是 Pre-Rendering 呢?
系列文
深入淺出,完整認識 Next.js 13 !30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言