Wen Chen
Published on

白話理解NextJS 的Pre-rendering

Authors
  • avatar
    Name
    Wen Chen

前言

NextJS 作為 React 最火紅的 Server-Side-Rendering(SSR)框架,本身也提供給使用者好幾種Data Fetching的方式,本文主要針對幾種方式做介紹。

本文並不會講解 SSR 對 SEO 有幫助的原因,或SSR與CSR的差異,對此還不了解者可以自行先搜尋理解一番。

getInitialProps作為 NextJS 較早期所提供的方式,在 NextJS 9.3 以後的版本,官方皆建議使用另外兩個本文會介紹到的方式,故本文並不會對此方式多加介紹。

本文接下來所指的server,都是指NextJs架構下的後端Node Server


Pre-rendering

馬上進入本文的重點,目前 NextJS 主要提供兩種 Pre-rendering 模式, 而 Pre-rendering 指的便是NextJs會預先將HTML產出,這也是SSR之所以對SEO有幫助的最大主因之一。

但在此之前,需先記得底下兩個詞:

  • Static Site Generation (SSG)
  • Server Side Rendering (SSR)

Server Side Rendering (SSR)

export async function getServerSideProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

在 NextJs 中,使用 getServerSideProps 來進行SSR,就如同字面上的意思,SSR 會在每一次 server 收到 request 時才去執行 pre-render 產出 HTML。

白話來說,要保證每次使用者拿到的都是最新的資料,那使用 SSR 準沒錯,初次使用時,如果要確保資料的正確無誤,將所有需要pre-rendering 的頁面都用 getServerSideProps 來撰寫,也是比較保險的做法。

然而,當所有頁面都被設置成SSR後,缺點也是顯而易見的:

大多數頁面都使用 SSR 後,由於每次造訪都需要依靠 server 去做即時的 render,會增加對 server 的負擔。

為此,NextJS提供了另一種方案。

Static Site Generation (SSG)

export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

在 NextJS 中,使用 getStaticProps 來執行SSG ,有別於SSR ,SSG會在專案run build的時候便預先將HTML頁面建構好。

也因為提前建構打包的特性,所以當有 dynamic routes 需要搭配 SSG 時, 就必須另外用上 getStaticPaths 將需要 pre-rendering 的路徑傳入 getStaticProps 來指定有哪些路徑要提前打包,
所以使用上可以將這兩個視為兩兄弟,當使用 SSG 的頁面為 dynamic routes 時, getStaticPaths 就必須上場了。

說了這麼多,SSG 最大的優點便是:

直接回傳預先建構好的 HTML,更甚是搭配 CDN 來做部署,整體來說 SSG 的頁面生成時間,都是會快於 SSR 的,亦可大量減少伺服器的負擔。

然而,因為頁面都是在 built time 即產生的,對於變動大,且需要讓使用者瀏覽即時資訊的網頁,並不適合使用 SSG ,且每次更動內容,便要重 Build 一次專案總體來說都是不切實際的。

於是乎,NextJS又送來了新的禮物

Incremental Static Regeneration (ISR)

ISR會在SSG頁面內加入一個 cache,再該 cache 過期後,下一次收到請求時,伺服器會先回傳前次的 cache,接著對該頁面重build一份新的HTML,在下一次收到請求後,顯示的便會是新的內容, 這麼做便可達到,不重 build 整份專案的情況下達到靜態內容的更新

而使用上也很易用,只需要在原先的 getStaticProps 中加入 revalidate 這個參數, 而裡面放置的是 cache 持續的時間, 這樣該頁面就可以在不重build的情況下,每10秒當接收到請求時自動重build一份新的HTML檔案。

export async function getStaticProps() {
  return {
    props: {
    },
    revalidate: 10, // In seconds
  }
}

上述三種(嚴格來說是兩種) pre-rendering,最終都會回傳已經在 server 端 build 好的 HTML 檔,也解決了SEO的痛點, 然而實際使用上還需因應情境來做評估和選用,這也是網站在規劃時很值得列入討論的點。

尤其是ISR、SSR、SSG在各網頁的搭配,如何有效降低伺服器的負擔,並提升網頁讀取的效能,肯定是一大課題。

名詞簡易對照表

結語

pre-rendering作為NextJS的主要核心,其提供的幾種行為肯定是很有趣的議題,本文僅簡單帶過說明。

裡面還有許多參數可以去做設定這部分在官方文件中都寫得非常詳細, ISR 和 getStaticPathsfallback 參數的搭配亦可以玩出不同的差異,這部分便留給大家自行去探索。


參考資料來源