自動靜態優化
如果頁面沒有阻塞性的資料需求,Next.js 會自動判定該頁面為靜態(可預先渲染)。此判定是根據頁面中是否缺少 getServerSideProps
和 getInitialProps
來進行的。
此功能讓 Next.js 能夠產生包含伺服器渲染與靜態生成頁面的混合式應用程式。
靜態生成的頁面仍然具有互動性:Next.js 會在客戶端進行水合 (hydrate),賦予其完整的互動能力。
這項功能的主要優勢之一是,經過優化的頁面無需伺服器端運算,可以從多個 CDN 節點立即串流傳送給終端使用者。結果就是為您的使用者帶來_極快_的載入體驗。
運作原理
如果頁面中包含 getServerSideProps
或 getInitialProps
,Next.js 會切換為按需渲染(即伺服器端渲染 (SSR))。
如果上述情況不存在,Next.js 將自動靜態優化您的頁面,將其預先渲染為靜態 HTML。
在預先渲染期間,路由器的 query
物件會是空的,因為在此階段我們無法提供 query
資訊。水合完成後,Next.js 會觸發應用程式更新,將路由參數提供給 query
物件。
以下情況會在水合後更新查詢參數,觸發另一次渲染:
- 頁面使用動態路由 (dynamic-route)
- 頁面的 URL 中包含查詢值
- 在
next.config.js
中設定了重寫規則 (rewrites),因為這些規則可能包含需要解析並提供給query
的參數
為了能夠判斷查詢參數是否已完全更新並可供使用,您可以利用 next/router
中的 isReady
欄位。
須知:使用動態路由添加到頁面的參數,若該頁面使用了
getStaticProps
,則這些參數始終會出現在query
物件中。
執行 next build
時,會為靜態優化的頁面產生 .html
檔案。例如,頁面 pages/about.js
的輸出結果會是:
而如果您在頁面中添加 getServerSideProps
,則會改為產生 JavaScript 檔案,如下所示:
注意事項
- 如果您在自訂
App
中使用了getInitialProps
,則未使用靜態生成 (Static Generation) 的頁面將無法啟用此優化功能。 - 如果您在自訂
Document
中使用了getInitialProps
,請確保在假設頁面為伺服器端渲染前檢查ctx.req
是否已定義。對於預先渲染的頁面,ctx.req
會是undefined
。 - 在路由器的
isReady
欄位為true
之前,請避免在渲染樹中使用next/router
的asPath
值。靜態優化的頁面僅在客戶端知道asPath
,伺服器端並不知曉,因此將其作為 prop 使用可能導致不一致錯誤。active-class-name
範例展示了一種將asPath
作為 prop 使用的方法。