如何自行託管 Next.js 應用程式
當部署您的 Next.js 應用程式時,您可能需要根據基礎架構配置不同功能的處理方式。
🎥 觀看影片: 深入了解自行託管 Next.js → YouTube (45 分鐘)。
圖片最佳化
透過 next/image
進行的圖片最佳化在使用 next start
部署時,無需配置即可自行託管。如果您希望使用單獨的服務來最佳化圖片,可以配置圖片載入器。
圖片最佳化可與靜態匯出一起使用,方法是在 next.config.js
中定義自訂圖片載入器。請注意,圖片是在執行時最佳化,而非建置期間。
須知事項:
- 在基於 glibc 的 Linux 系統上,圖片最佳化可能需要額外配置以防止過度記憶體使用。
- 深入了解最佳化圖片的快取行為以及如何配置 TTL。
- 如果您願意,也可以停用圖片最佳化,同時保留使用
next/image
的其他好處。例如,如果您自行單獨最佳化圖片。
中介軟體
中介軟體在使用 next start
部署時,無需配置即可自行託管。由於它需要存取傳入請求,因此在使用靜態匯出時不受支援。
中介軟體使用邊緣運行時,這是所有可用 Node.js API 的子集,以幫助確保低延遲,因為它可能在應用程式的每個路由或資產前運行。如果您不希望這樣,可以使用完整的 Node.js 運行時來運行中介軟體。
如果您希望新增需要所有 Node.js API 的邏輯(或使用外部套件),您可能可以將此邏輯移至佈局作為伺服器元件。例如,檢查標頭和重新導向。您也可以使用標頭、Cookie 或查詢參數透過 next.config.js
進行重新導向或重寫。如果這不起作用,您也可以使用自訂伺服器。
環境變數
Next.js 支援建置時和執行時環境變數。
預設情況下,環境變數僅在伺服器上可用。要將環境變數公開給瀏覽器,必須加上 NEXT_PUBLIC_
前綴。然而,這些公開環境變數將在 next build
期間內聯到 JavaScript 套件中。
您可以安全地在動態渲染期間在伺服器上讀取環境變數。
這允許您使用單一的 Docker 映像,可以在多個環境中推廣,並使用不同的值。
須知事項:
- 您可以使用
register
函式在伺服器啟動時執行程式碼。- 我們不建議使用 runtimeConfig 選項,因為這不適用於獨立輸出模式。相反,我們建議逐步採用應用程式路由器。
快取與 ISR
Next.js 可以快取回應、生成的靜態頁面、建置輸出以及其他靜態資產,如圖片、字型和腳本。
快取和重新驗證頁面(使用增量靜態再生)使用相同的共享快取。預設情況下,此快取儲存在 Next.js 伺服器的檔案系統(磁碟)上。這在使用頁面和應用程式路由器自行託管時自動運作。
如果您希望將快取的頁面和資料持久化到持久儲存,或在 Next.js 應用程式的多個容器或實例之間共享快取,可以配置 Next.js 快取位置。
自動快取
- Next.js 將
Cache-Control
標頭設定為public, max-age=31536000, immutable
給真正不可變的資產。這無法覆蓋。這些不可變檔案在檔案名稱中包含 SHA 雜湊,因此可以安全地永久快取。例如,靜態圖片匯入。您可以配置 TTL 給圖片。 - 增量靜態再生 (ISR) 將
Cache-Control
標頭設定為s-maxage: <revalidate in getStaticProps>, stale-while-revalidate
。此重新驗證時間在您的getStaticProps
函式中以秒為單位定義。如果您設定revalidate: false
,它將預設為一年的快取持續時間。 - 動態渲染的頁面將
Cache-Control
標頭設定為private, no-cache, no-store, max-age=0, must-revalidate
以防止使用者特定資料被快取。這適用於應用程式路由器和頁面路由器。這也包括草稿模式。
靜態資產
如果您希望在不同的網域或 CDN 上託管靜態資產,可以在 next.config.js
中使用 assetPrefix
配置。Next.js 將在檢索 JavaScript 或 CSS 檔案時使用此資產前綴。將資產分離到不同的網域會帶來 DNS 和 TLS 解析的額外時間。
配置快取
預設情況下,生成的快取資產將儲存在記憶體中(預設為 50mb)和磁碟上。如果您使用 Kubernetes 等容器編排平台託管 Next.js,每個 pod 將擁有快取的副本。為了防止顯示過時資料,因為預設情況下快取不在 pod 之間共享,您可以配置 Next.js 快取以提供快取處理程式並停用記憶體快取。
在自行託管時配置 ISR/資料快取位置,您可以在 next.config.js
檔案中配置自訂處理程式:
然後,在專案的根目錄中建立 cache-handler.js
,例如:
使用自訂快取處理程式將允許您確保所有託管 Next.js 應用程式的 pod 之間的一致性。例如,您可以將快取值儲存在任何地方,如 Redis 或 AWS S3。
須知事項:
revalidatePath
是快取標籤上的便利層。呼叫revalidatePath
將使用提供的頁面的特殊預設標籤呼叫revalidateTag
函式。
建置快取
Next.js 在 next build
期間生成一個 ID,以識別正在提供的應用程式版本。相同的建置應在多個容器中使用和啟動。
如果您為環境的每個階段重新建置,則需要生成一致的建置 ID 以在容器之間使用。在 next.config.js
中使用 generateBuildId
命令:
版本偏差
Next.js 將自動緩解大多數版本偏差的實例,並在檢測到時自動重新載入應用程式以檢索新資產。例如,如果 deploymentId
不匹配,頁面之間的轉換將執行硬導航而非使用預取值。
當應用程式重新載入時,如果未設計為在頁面導航之間持久化,則可能會丟失應用程式狀態。例如,使用 URL 狀態或本地儲存將在頁面重新整理後持久化狀態。然而,元件狀態如 useState
將在此類導航中丟失。
串流與 Suspense
Next.js 應用程式路由器在自行託管時支援串流回應。如果您使用 Nginx 或類似代理,則需要配置它以停用緩衝來啟用串流。
例如,您可以透過將 X-Accel-Buffering
設定為 no
來在 Nginx 中停用緩衝:
部分預渲染
部分預渲染(實驗性)預設與 Next.js 一起運作,並非僅限於 CDN 的功能。這包括作為 Node.js 伺服器(透過 next start
)部署以及與 Docker 容器一起使用時。
與 CDN 一起使用
當在 Next.js 應用程式前使用 CDN 時,頁面將在存取動態 API 時包含 Cache-Control: private
回應標頭。這確保生成的 HTML 頁面標記為不可快取。如果頁面完全預渲染為靜態,它將包含 Cache-Control: public
以允許頁面在 CDN 上快取。
如果您不需要混合靜態和動態元件,可以將整個路由設為靜態並在 CDN 上快取輸出 HTML。如果在執行 next build
時未使用動態 API,則此自動靜態最佳化是預設行為。
隨著部分預渲染趨於穩定,我們將透過部署適配器 API 提供支援。
after
after
在使用 next start
自行託管時完全支援。
停止伺服器時,請透過發送 SIGINT
或 SIGTERM
信號並等待來確保優雅關機。這允許 Next.js 伺服器等待直到 after
內使用的待處理回呼函式或承諾完成。