Skip to main content

Next.js 渲染攻略:SSR、CSR、ISR 怎麼選?

1. SSR(Server-Side Rendering,伺服器端渲染)

什麼是 SSR?

SSR 是在伺服器端生成完整的 HTML 內容,然後將其傳送給瀏覽器。每次使用者請求頁面時,伺服器都會動態生成最新的 HTML。

特點:

  • SEO 友好:因為伺服器直接傳送完整的 HTML,搜尋引擎可以輕易爬取內容。

  • 首次載入速度快:使用者會立即看到完整的頁面內容,不需等待 JavaScript 在瀏覽器執行。

  • 伺服器負擔較重:每次請求都需要伺服器重新生成 HTML,對於高流量網站可能需要更多伺服器資源。

  • 互動性稍慢:頁面雖然快速顯示,但需要等待伺服器回應,且後續的互動可能需要額外的客戶端 JavaScript。

什麼時候使用 SSR?

  • 頁面內容高度依賴動態數據(例如即時更新的新聞頁面)。

  • 需要優化 SEO 的頁面。

  • 希望使用者快速看到完整內容。

Next.js 中的 SSR 實現

在 Next.js 中,SSR 使用 getServerSideProps 函數來實現。這個函數在每次請求時於伺服器端執行,獲取數據並傳遞給頁面元件。

程式碼範例

假設你正在建一個顯示即時用戶資料的頁面:

// pages/user/[id].js
import React from 'react';

export default function UserProfile({ user }) {
return (
<div>
<h1>用戶資料</h1>
<p>姓名:{user.name}</p>
<p>電子郵件:{user.email}</p>
</div>
);
}

export async function getServerSideProps(context) {
const { id } = context.params; // 從 URL 獲取動態參數
// 模擬從 API 獲取用戶資料
const response = await fetch(`https://api.example.com/users/${id}`);
const user = await response.json();

return {
props: {
user, // 將數據傳遞給元件
},
};
}

步驟解析:

  1. 當使用者訪問 /user/123 時,Next.js 會在伺服器端執行 getServerSideProps。

  2. getServerSideProps 從 API 獲取用戶資料,並將其作為 props 傳遞給 UserProfile 元件。

  3. 伺服器生成完整的 HTML 並傳送給瀏覽器。

  4. 使用者立即看到渲染好的頁面。

注意事項:

  • getServerSideProps 只在伺服器端執行,不能在瀏覽器端運行。

  • 如果 API 回應慢,頁面載入時間會變長,因為伺服器必須等待數據。


2. CSR(Client-Side Rendering,客戶端渲染)

什麼是 CSR?

CSR 是指頁面的 HTML 由瀏覽器中的 JavaScript 動態生成。伺服器僅提供一個空的 HTML 框架,JavaScript 在客戶端執行後才渲染出內容。

特點:

  • 首次載入慢:使用者需要等待 JavaScript 下載、解析並執行,才能看到頁面內容。

  • SEO 不友好:因為初始 HTML 幾乎是空的,搜尋引擎可能無法正確爬取內容。

  • 伺服器負擔輕:伺服器只需傳送靜態檔案(HTML、CSS、JavaScript),無需動態生成內容。

  • 互動性強:適合需要高度互動的應用,例如單頁應用(SPA)。

什麼時候使用 CSR?

  • 頁面內容高度依賴用戶互動(例如即時聊天應用)。

  • 不需要 SEO 或 SEO 不是首要考量。

  • 希望減少伺服器負擔。

Next.js 中的 CSR 實現

在 Next.js 中,CSR 通常透過 React 的 useEffect 和 useState 來實現數據獲取和渲染。Next.js 預設會將頁面作為靜態頁面處理,但你可以在客戶端動態獲取數據。

程式碼範例

假設你正在建一個顯示用戶清單的頁面:

// pages/users.js
import React, { useState, useEffect } from 'react';

export default function UsersList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
async function fetchUsers() {
setLoading(true);
// 模擬從 API 獲取用戶清單
const response = await fetch('https://api.example.com/users');
const data = await response.json();
setUsers(data);
setLoading(false);
}
fetchUsers();
}, []);

if (loading) {
return <div>載入中...</div>;
}

return (
<div>
<h1>用戶清單</h1>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}

步驟解析:

  1. 頁面載入時,Next.js 傳送一個空的 HTML 框架和 JavaScript 檔案。

  2. 瀏覽器執行 useEffect,向 API 發送請求並獲取用戶清單。

  3. 數據獲取完成後,React 更新狀態並重新渲染頁面,顯示用戶清單。

  4. 在數據載入期間,顯示「載入中...」以提升用戶體驗。

注意事項:

  • 如果 JavaScript 檔案很大或網路慢,使用者可能會看到空白頁面或載入指示器。

  • 搜尋引擎可能無法正確索引動態生成的內容。


3. ISR(Incremental Static Regeneration,增量靜態再生)

什麼是 ISR?

ISR 是 Next.js 提供的一種混合渲染方式,結合了靜態生成(SSG)和動態更新的優點。頁面在建置時生成靜態 HTML,但可以設定一個週期(例如每 60 秒),讓 Next.js 在背景重新生成頁面,更新內容。

特點:

  • SEO 友好:生成的是靜態 HTML,搜尋引擎可以輕易爬取。

  • 首次載入快:靜態頁面直接從 CDN 提供,無需伺服器即時運算。

  • 動態更新:透過設定 revalidate 時間,頁面可以定期更新,無需重新建置整個網站。

  • 靈活性高:適合需要定期更新的內容,例如部落格文章或產品頁面。

什麼時候使用 ISR?

  • 頁面內容需要定期更新,但不需要即時動態數據。

  • 希望兼顧 SEO 和快速載入體驗。

  • 適合流量較高的網站,因為靜態頁面可由 CDN 提供,減少伺服器負擔。

Next.js 中的 ISR 實現

在 Next.js 中,ISR 使用 getStaticProps 並搭配 revalidate 選項來實現。getStaticProps 在建置時執行,生成靜態頁面,而 revalidate 指定頁面重新生成的週期。

程式碼範例

假設你正在建一個顯示最新部落格文章的頁面:

// pages/blog.js
import React from 'react';

export default function Blog({ posts }) {
return (
<div>
<h1>最新文章</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}

export async function getStaticProps() {
// 模擬從 API 獲取文章資料
const response = await fetch('https://api.example.com/posts');
const posts = await response.json();

return {
props: {
posts, // 將文章資料傳遞給元件
},
revalidate: 60, // 每 60 秒重新生成頁面
};
}

步驟解析:

  1. 在建置時,Next.js 執行 getStaticProps,從 API 獲取文章資料並生成靜態 HTML。

  2. 靜態頁面儲存在伺服器或 CDN,供使用者快速訪問。

  3. 當使用者訪問頁面時,Next.js 提供靜態 HTML,無需即時運算。

  4. 每 60 秒(由 revalidate: 60 指定),Next.js 在背景檢查是否有新數據,若有則重新生成頁面。

  5. 如果 API 數據更新,使用者會在下一次請求時看到最新的靜態頁面。

注意事項:

  • revalidate 的時間單位是秒,設定太短可能增加伺服器負擔,太長則可能導致內容不夠即時。

  • 如果 API 請求失敗,Next.js 會繼續提供舊的靜態頁面,確保網站可用性。


SSR、CSR、ISR 的比較表

特性SSR(伺服器端渲染)CSR(客戶端渲染)ISR(增量靜態再生)
渲染地點伺服器端客戶端(瀏覽器)建置時 + 伺服器端(背景更新)
首次載入速度快(伺服器生成 HTML)慢(需下載 JS 並執行)非常快(靜態 HTML 從 CDN 提供)
SEO 友好性
伺服器負擔高(每次請求都生成)低(僅傳送靜態檔案)低(靜態頁面 + 背景更新)
數據即時性高(每次請求都更新)高(客戶端即時請求)中(取決於 revalidate 時間)
使用場景動態內容、SEO 重要高度互動的應用定期更新的內容、SEO 重要

如何選擇?

  1. 如果需要 SEO 和快速首次載入

    • 首選 ISR,因為它兼顧了靜態生成的性能和動態更新的靈活性。

    • 如果內容必須即時更新,選擇 SSR

  2. 如果頁面高度互動且 SEO 不是重點

    • 使用 CSR,例如儀表板或即時應用。
  3. 如果網站流量高

    • ISR 或靜態生成(SSG)更適合,因為它們利用 CDN 減少伺服器負擔。