預先渲染允許您藉由在建置時而非執行時渲染頁面,來加速靜態內容的頁面載入速度。預先渲染透過 react-router.config.ts
中的 prerender
設定啟用,並且可以根據 ssr
設定值以兩種方式使用
ssr:true
預先渲染將 prerender
選項新增至您的設定,共有三種簽名
import type { Config } from "@react-router/dev/config";
export default {
// Can be omitted - defaults to true
ssr: true,
// all static paths (no dynamic segments like "/post/:slug")
prerender: true,
// specific paths
prerender: ["/", "/blog", "/blog/popular-post"],
// async function for dependencies like a CMS
async prerender({ getStaticPaths }) {
let posts = await fakeGetPostsFromCMS();
return [
"/",
"/blog",
...posts.map((post) => post.href),
];
},
} satisfies Config;
預先渲染沒有額外的應用程式 API。正在預先渲染的路徑使用與伺服器渲染相同的路由 loader
函數
export async function loader({ request, params }) {
let post = await getPost(params.slug);
return post;
}
export function Post({ loaderData }) {
return <div>{loaderData.title}</div>;
}
建置會建立一個 new Request()
並像伺服器一樣在您的應用程式中執行,而不是請求傳送到已部署伺服器上的路由。
當伺服器渲染時,對尚未預先渲染的路徑的請求將照常進行伺服器渲染。
渲染結果將寫出到您的 `build/client` 目錄。您會注意到每個路徑有兩個檔案
[url].html
用於初始文件請求的 HTML 檔案[url].data
用於用戶端導航瀏覽器請求的檔案您的建置輸出將指示哪些檔案已預先渲染
> react-router build
vite v5.2.11 building for production...
...
vite v5.2.11 building SSR bundle for production...
...
Prerender: Generated build/client/index.html
Prerender: Generated build/client/blog.data
Prerender: Generated build/client/blog/index.html
Prerender: Generated build/client/blog/my-first-post.data
Prerender: Generated build/client/blog/my-first-post/index.html
...
在開發期間,預先渲染不會將渲染結果儲存到 public 目錄,這僅在 `react-router build` 時發生。
ssr:false
預先渲染上述範例假設您正在部署執行階段伺服器,但正在預先渲染一些靜態頁面,以便更快地提供它們並避免點擊伺服器。
若要停用執行階段 SSR 並設定從靜態檔案伺服器提供預先渲染,您可以設定 ssr:false
設定旗標
import type { Config } from "@react-router/dev/config";
export default {
ssr: false, // disable runtime server rendering
prerender: true, // pre-render all static routes
} satisfies Config;
如果您在未指定 prerender
設定的情況下指定 ssr:false
,React Router 將其稱為 SPA 模式。在 SPA 模式中,我們渲染一個能夠為您應用程式的 *任何* 路徑進行 hydration 的單一 HTML 檔案。它可以做到這一點,因為它只將 root
路由渲染到 HTML 檔案中,然後在 hydration 期間根據瀏覽器 URL 確定要載入哪些子路由。這表示您可以在 root 路由上使用 `loader`,但不能在任何其他路由上使用,因為我們在瀏覽器中 hydration 之前不知道要載入哪些路由。
如果您想要使用 ssr:false
預先渲染路徑,那些相符的路徑 *可以* 具有 loader,因為我們將預先渲染這些路徑的所有相符路由,而不僅僅是 root。當設定 `ssr:false` 時,您無法在任何路由中包含 `actions` 或 `headers` 函數,因為將沒有執行階段伺服器來執行它們。
如果您想要 ssr:false
但不想預先渲染 *所有* 路由 - 這也沒問題!您可能有一些路徑需要預先渲染的效能/SEO 優勢,但其他頁面使用 SPA 即可。
您也可以使用設定選項的組合來做到這一點 - 只需將您的 prerender
設定限制為您想要預先渲染的路徑,React Router 也會輸出一個 "SPA 後備" HTML 檔案,可用於提供 hydration 任何其他路徑 (使用與 SPA 模式相同的方法)。
這將寫入到以下路徑之一
build/client/index.html
- 如果 /
路徑未預先渲染build/client/__spa-fallback.html
- 如果 /
路徑已預先渲染import type { Config } from "@react-router/dev/config";
export default {
ssr: false,
// SPA fallback will be written to build/client/index.html
prerender: ["/about-us"],
// SPA fallback will be written to build/client/__spa-fallback.html
prerender: ["/", "/about-us"],
} satisfies Config;
您可以設定您的部署伺服器,以便為任何原本會 404 的路徑提供此檔案。某些主機預設會執行此操作,但其他主機則不會。例如,主機可能支援 _redirects
檔案來執行此操作
# If you did not pre-render the `/` route
/* /index.html 200
# If you pre-rendered the `/` route
/* /__spa-fallback.html 200
如果您在應用程式的有效路由上收到 404 錯誤,則可能是您需要設定您的主機。
這是另一個關於如何使用 sirv-cli
工具執行此操作的範例
# If you did not pre-render the `/` route
sirv-cli build/client --single index.html
# If you pre-rendered the `/` route
sirv-cli build/client --single __spa-fallback.html
當使用 ssr:false
進行預先渲染時,如果您有無效的匯出,React Router 將在建置時產生錯誤,以幫助防止一些容易被忽略的錯誤。
headers
/action
函數,因為將沒有執行階段伺服器來執行它們prerender
設定 (SPA 模式) 的情況下使用 ssr:false
時,僅允許在 root 路由上使用 loader
prerender
設定的情況下使用 ssr:false
時,允許在 prerender
路徑比對的任何路由上使用 loader
loader
,您需要確保父 loaderData
可以在執行時正確地確定,方法是loader
並渲染到 .data
檔案中,或者clientLoader
,可以在執行時針對非預先渲染的子路徑呼叫它