2023/04/07 # 快速了解Next.js中的網頁渲染技術重點: SSR、SSG、ISR與CSR ## 前言 Next.js 是 React 的網頁框架。在學習使用 Next.js 開發的時候,我們會接觸到四種常見的網頁渲染技術。我們需要考量該選擇使用哪些網頁渲染技術,較為適合開發中的網站或應用程式。 先解釋一下這四種技術的英文縮寫: SSR:Server Side Rendering,伺服器端渲染 SSG:Static Site Generation,靜態網站生成 ISR:Incremental Site Rendering,增量式的網站渲染 CSR:Client Side Rendering,客戶端(通常是瀏覽器)渲染 ## Next.js pre-rendering 預渲染 Next.js 有一個特點是支援預渲染,預設會預渲染每個頁面,目的是可以帶來更好的性能以及 SEO。 Next.js 會將網站的所有頁面提前生成靜態 HTML 文件並保存下來,如此一來當使用者訪問網站時,伺服器會回傳預渲染好的靜態 HTML 文件,而不是使用 JavaScript 動態生成網頁內容。 Next.js 的預渲染又分為兩種形式,分別是**靜態網站生成 SSG(Static Site Generation)** 和**伺服器端渲染 SSR(Server Side Rendering)**。 ## SSR 伺服器端渲染 - 可以讓伺服器動態地注入資料到 HTML 的檔案中,讓客戶端第一次請求拿到的 HTML 就已經包含所有的資料,因此 google 爬蟲也就可以順利地爬到網站中的內容,利於 SEO。 - 因為每次請求都會重新生成頁面,使用 SSR 就必須有個伺服器一直處理使用者的請求,一直產生有資料的 HTML,並送到客戶端,這樣的工作對於伺服器來說是一個負擔。 - 適合需要經常展示更新數據資料的網站。 ### 獲取資料的方式 - 將在伺服器端的每個頁面請求中執行一個異步函數`getServerSideProps`以從 API 獲取資料。 - 載入頁面之前,首先將執行該函數並產生延遲,然後再為頁面提供服務。 ## SSG 靜態網站生成 - 所有的內容都在 **連結(build)** 的時候都打包進入檔案中,所以使用者在瀏覽網站時,就可以拿到完整的HTML檔案。 - 除了有利於 SEO 之外,還有因為每次使用者拿到的 HTML 內容都不會變,所以還可以讓 HTML 被 **cache** 在 CDN 上,很適合用在**資料變動較小**的網頁中,像是部落格、產品介紹頁這種應用中。 ### 獲取資料的方式 - 執行特殊函數:`getStaticProps`來獲取一次數據。 ## `getServerSideProps` vs. `getStaticProps` `getServerSideProps` 和 `getStaticProps` 是 Next.js 中用於資料預取的兩個函數: - getServerSideProps 會在每次請求時都重新取得資料,而 getStaticProps 則是在編譯時就取得資料,並將資料儲存在靜態檔案中。 - 使用 getServerSideProps 時,網頁的載入速度會比較慢,但是資料是最新的。 - 當使用 getStaticProps 時,網頁的載入速度會比使用 getServerSideProps 更快,但是資料可能不是最新的。 如果要網頁在每次請求時都重新取得資料,則應該使用 `getServerSideProps`。如果您需要在編譯時就取得資料,則應該使用 `getStaticProps`。如果您需要在編譯時就取得資料,但是又希望資料是最新的,則可以使用 `revalidate`屬性。 ## ISR 增量式的網站渲染 ISR基本上是SSG和SSR的結合體。在首次生成靜態頁面之後,有新數據時會重新生成該頁面。ISR適用於需要SEO最佳化和首次載入速度快且需要動態更新內容的網頁。 使用ISR需要在`getStaticProps`函數中添加`revalidate`屬性,並指定一個秒數,表示多久重新產生一次頁面。例如: `revalidate: 10` 表示每10秒重新產生一次頁面。 ### 獲取資料的方式 - 執行特殊函數: `getStaticProps` + `revalidate` ## CSR 客戶端渲染 - 只要上述的這些 API,例如 `getStaticProps` 、`getServerSideProps` ... 我們都沒有使用,數據都是通過在組件內部使用 `axios`或者`fetch`去發送請求獲取並渲染的,那麼我們使用的就是純客戶端渲染了。 - 這種方式與SSR是相對的,使用上需分離前後端。 - 渲染資料的所有過程都交由客戶端(瀏覽器)處理,使用者在瀏覽網站時,第一次跟伺服器請求的 HTML 檔裡面幾乎不包含任何的內容,伺服器並沒有傳入資料到 HTML。接著,後續會再透過載入的 bundle,也就是 JavaScript 的檔案,再讓 JS 執行 AJAX 跟伺服器請求資料,最後將資料渲染到畫面上,使用者會比較慢看到網頁的內容。 ### 獲取資料的方式 - 使用 `useEffect` 函數。 - 它會在客戶端的每個頁面請求中從 API 獲取數據(頁面被渲染後,函數將執行)。 ## 小結與簡單比較 - SSR 是在每次請求時動態地從 API 獲取數據並注入到 HTML 中,可以提高 SEO 效果,但會增加伺服器的負擔。適合用於需要經常展示更新數據的網站。 - SSG 是在 build 時就生成所有頁面和數據,可以提高性能和安全性,但不適合用於需要動態更新數據的網站。適合用於資料變動較小的網站。 - ISR 是在首次生成靜態頁面後,每當有新數據時會重新生成該頁面,可以結合 SSG 和 SSR 的優勢,既可以提高 SEO 效果和首次加載速度,又可以動態更新內容。適合用於需要 SEO 優化和首次加載速度快且需要動態更新內容的網站,且需要配置`revalidate`參數來控制更新頻率。 - CSR 是在 bundle 載入後才跟伺服器要數據,可以減少伺服器的負擔,但會降低 SEO 效果和首次加載速度。適合用於不需要 SEO 優化和首次加載速度快且需要前後端分離的網站。 ## 參考 - 官方文件 https://nextjs.org/docs/pages/building-your-application/data-fetching - 實驗非常仔細的fetch API loading比較 https://theodorusclarence.com/blog/nextjs-fetch-method https://theodorusclarence.com/blog/nextjs-fetch-usecase - 有範例參考的詳盡介紹 https://juejin.cn/post/7213653429415559223
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.