邁向成品

在推出你的 Next.js 應用程式做為成品前,可以參考這些用來確保最佳使用者體驗的建議。

通用的建議

快取

範例

快取可以改善回應的時間及減少外部服務的請求次數。 Next.js 會自動針對位於 /_next/static 中不會改變的材料(assets)—— JavaScript 、 CSS 、靜態圖片、其他媒體——加上快取標頭。

Cache-Control: public, max-age=31536000, immutable

next.config.js 中設定的 Cache-Control 標頭會在最終成品中被改寫,以確保最後的靜態材料可以被有效地快取。如果你有需要對某個透過靜態產生後快取的頁面進行重新驗證,可以在該頁面的 getStaticProps 函式中設定 revalidate 。如果用了 next/image ,也有針對預設圖片最佳化載入的特殊快取規則 可以參考。

備註: 在本機以 next dev 指令執行應用程式時,你所自訂的標頭會被改寫以避免在本機開發時被快取住。

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

你也可以在 getServerSideProps 及 API 路由中使用快取來做到動態回應。譬如使用 stale-while-revalidate

// 這個設定值( s-maxage=10 )可讓內容在 10 秒內都視為是新的。 // 就算再接下來的 10 秒內有重複的請求,目前快取的內容仍會被視為是新的。 // 這個設定值( stale-while-revalidate=59 )則表示若在 59 秒內發生重複的請求, // 快取的內容會被視為舊的但仍會被成像出來。 // // 重新驗證的請求會在背景中發出來替換最新的內容到快取中, // 在重新整理頁面後就會看到新的內容出現了。 export async function getServerSideProps({ req, res }) { res.setHeader( 'Cache-Control', 'public, s-maxage=10, stale-while-revalidate=59' ) return { props: {}, } }

預設的情況下, Cache-Control 標頭會因頁面拿取資料的方式而異。

  • 如果該頁面使用了 getServerSidePropsgetInitialProps ,在預設的情況下, Cache-Control 會由 next start 來設定,以避免不經意地對不該被快取的回應做快取。如果想在使用 getServerSideProps 時套用不同的快取行為,可以像上述展示的那樣,在函式內用 res.setHeader('Cache-Control', 'value_you_prefer')
  • 如果使用了 getStaticProps , 該頁面就會具有 Cache-Control 標頭及 s-maxage=REVALIDATE_SECONDS, stale-while-revalidate 的設定值。若 revalidate 未被使用 則採用 s-maxage=31536000, stale-while-revalidate 的方式來最大化快取的壽命。

備註: 你的部署服務供應商必須支援動態回應的快取。若採用自架伺服器,則需要自行把相關的邏輯存檔在譬如 Redis 這樣的鍵值儲存庫中。如果採用 Vercel 進行部署,邊緣快取不需要額外設定.

減少 JavaScript 的大小

範例

藉由下列的工具可以理解每一個 JavaScript 封裝檔案中涵蓋了哪些東西,進而減少傳送到瀏覽器的 JavaScript 總數:

  • Import Cost – 在 VSCode 中顯示匯入套件的大小。
  • Package Phobia – 找出加入到專案的開發依賴所需的成本。
  • Bundle Phobia – 分析某個依賴對最終輸出的大小有多少影響。
  • Webpack Bundle Analyzer – 視覺化 webpack 輸出檔案的大小,同時提供可互動及可縮放的樹狀圖。
  • bundlejs – 快速封裝及最小化專案的線上工具,還可以檢視壓縮後的 gzip 或 brotli 的大小,它直接透過瀏覽器在本機執行。

next build 的過程中會自動把位於 pages/ 目錄中的每個檔案做程式碼拆分為屬於它自己的 JavaScript 封裝檔。當然也可以用動態匯入的方式來惰性載入元件及函式庫。好比說,你希望延後載入模態彈窗( modal )的程式碼,直到使用者點選開啟按鈕再載入。

紀錄

範例

鑒於 Next.js 同時執行於客戶端及伺服端,因此支援多種型式的紀錄方式:

  • 在瀏覽器的 console.log
  • 在伺服器的 stdout

若目標是結構化的紀錄方式,推薦使用 Pino 。若使用 Vercel ,則內建整合了相容於 Next.js 的紀錄方式。

錯誤處理

範例

你可以控制使用者在遭遇程式發生錯誤時顯示 500 頁面 的體驗。與其使用 Next.js 預設的主題,建議自訂這些錯誤頁面以符合品牌的形象。

同時可以透過諸如 Sentry 這類的工具來追蹤例外事件。這個範例 展示如何使用 Sentry SDK 來對 Next.js 的客戶端及伺服端進行錯誤的捕捉及回報。另外,還有針對 Vercel 的 Sentry 整合.

載入效能

在開始改善載入效能前,必須先決定要衡量什麼及如何衡量。作為經由網路瀏覽器進行衡量的工具, Core Web Vitals 是優良的產業標準。若你尚不清楚 Core Web Vitals 的衡量指標,請檢閱這篇[部落格文章]並找出那些能改善載入效能的特殊指標。下列這些事項是衡量載入效能的理想環境:

  • 實驗環境,使用你的電腦或模擬器。
  • 實際環境,使用真實世界訪客的資料。
  • 本機環境,使用執行在你的裝置的測試。
  • 遠端環境,使用執行在雲端的測試。

當準備就緒後,採用一次只套用一個策略的方式進行測量,觀察改進的結果並持續調整直到不再有顯著的改進幅度為止。接著,再套用下一個策略。

  • 使用離你的資料庫或 API 部署地點最接近的快取區域。
  • 如同快取區塊所提到的,使用 stale-while-revalidate 快取值以避免對後端造成超載。
  • 使用增量靜態重新產出來減少對後端的請求數。
  • 移除不使用的 JavaScript 。檢閱這個部落格來搞懂 Core Web Vitals 衡量哪些影響封裝檔大小的事項以及哪些是可以被用來減少大小的策略,譬如:
    • 設定那些可以在程式碼編輯器中檢視匯入成本及大小的工具
    • 找尋更小的可替代項目
    • 動態地載入元件及依賴
    • 更詳盡的資訊,請參閱這個指南效能檢查清單

相關資訊

以下是可以更進一步採取的措施:

本篇文章由t7yang

t7yang

貢獻翻譯。瞭解如何參與貢獻