跳到內容
返回部落格

2024 年 4 月 11 日 星期四

Next.js 14.2

發布者

Next.js 14.2 包含開發、生產和快取方面的改進。

立即升級或開始使用

終端機
npx create-next-app@latest

Turbopack 開發版 (發佈候選版)

在過去幾個月中,我們一直致力於透過 Turbopack 改善本機開發效能。在 14.2 版本中,Turbopack 發佈候選版現已可用於本機開發

  • 99.8%整合測試現在已通過。
  • 我們已驗證 Next.js 應用程式中使用的前 300 個 npm 套件可以使用 Turbopack 編譯。
  • 所有Next.js 範例都可與 Turbopack 搭配使用。
  • 我們已整合Lightning CSS,這是一個以 Rust 撰寫的快速 CSS 打包器和壓縮器。

我們一直在 Vercel 的應用程式中廣泛地試用 Turbopack。例如,對於 vercel.com 這個大型 Next.js 應用程式,我們觀察到:

  • 本機伺服器啟動速度提升高達 76.7%
  • 使用 Fast Refresh 進行程式碼更新速度提升高達 96.3%
  • 首次路由編譯速度提升高達 45.8%,且不使用快取 (Turbopack 尚無磁碟快取)。

Turbopack 仍為可選功能,您可以使用以下方式試用:

終端機
next dev --turbo

我們現在將專注於改善記憶體使用量、實作持久快取和 next build --turbo

  • 記憶體使用量 - 我們已建置用於調查記憶體使用量的底層工具。您現在可以產生追蹤檔,其中包含效能指標和廣泛的記憶體使用量資訊。這些追蹤檔讓我們能夠在無需存取您的應用程式原始碼的情況下,調查效能和記憶體使用量。
  • 持久快取 - 我們也在探索最佳架構選項,並預計在未來的版本中分享更多詳細資訊。
  • next build - 雖然 Turbopack 尚不適用於建置,但已有 74.7% 的測試通過。您可以在 areweturboyet.com/build 上追蹤進度。

若要查看 Turbopack 中支援不支援的功能清單,請參閱我們的文件

建置和生產改進

除了使用 Turbopack 改善打包之外,我們還致力於改善所有 Next.js 應用程式 (Pages 和 App Router) 的整體建置和生產效能。

Tree-shaking

我們針對伺服器和用戶端元件之間的邊界識別出一項最佳化,可以 tree-shaking 未使用的 exports。例如,從具有 "use client" 的檔案匯入單個 Icon 元件,不再包含該套件中的所有其他圖示。這可以大幅縮減生產 JavaScript 套件大小。

在像 react-aria-components 這樣的熱門程式庫上測試此最佳化,最終套件大小縮減了 -51.3%

注意: 此最佳化目前不適用於 barrel 檔案。在此期間,您可以使用 optimizePackageImports 設定選項

next.config.ts
module.exports = {
  experimental: {
    optimizePackageImports: ['package-name'],
  },
};

建置記憶體使用量

對於極大型的 Next.js 應用程式,我們注意到在生產建置期間發生記憶體不足崩潰 (OOM)。在調查使用者報告和重現後,我們確定根本問題是過度打包和壓縮 (Next.js 建立的 JavaScript 檔案較少但較大,且有重複)。我們已重構打包邏輯並針對這些情況優化了編譯器。

我們的早期測試顯示,在最小型的 Next.js 應用程式上,記憶體使用量和快取檔案大小平均從 2.2GB 減少到 190MB 以下

為了更輕鬆地偵錯記憶體效能,我們在 next build 中引入了 --experimental-debug-memory-usage 標記。在我們的文件中瞭解更多資訊。

CSS

我們更新了在生產 Next.js 建置期間優化 CSS 的方式,透過將 CSS 分塊以避免在頁面之間導航時發生樣式衝突。

CSS 塊的順序和合併現在由匯入順序定義。例如,base-button.module.css 將在 page.module.css 之前排序

base-button.tsx
import styles from './base-button.module.css';
 
export function BaseButton() {
  return <button className={styles.primary} />;
}
page.tsx
import { BaseButton } from './base-button';
import styles from './page.module.css';
 
export function Page() {
  return <BaseButton className={styles.primary} />;
}

為了維持正確的 CSS 順序,我們建議

  • 使用 CSS Modules 而非 全域樣式
  • 僅在單個 JS/TS 檔案中匯入 CSS Module。
  • 如果使用全域類別名稱,也請在同一個 JS/TS 中匯入全域樣式。

我們不預期此變更會對大多數應用程式產生負面影響。但是,如果您在升級時看到任何非預期的樣式,請根據我們文件中的建議,檢查您的 CSS 匯入順序。

快取改進

快取是建置快速且可靠的 Web 應用程式的關鍵部分。在執行變更時,使用者和開發人員都希望快取能夠更新,以反映最新的變更。我們一直在探索如何改善 App Router 中 Next.js 的快取體驗。

staleTimes (實驗性功能)

用戶端 Router 快取是一個快取層,旨在透過快取用戶端上已瀏覽和預先擷取的路由來提供快速的導航體驗。

根據社群回饋,我們新增了一個實驗性的 staleTimes 選項,允許設定用戶端 router 快取的失效期限。

預設情況下,預先擷取的路由 (使用不含 prefetch prop 的 <Link> 元件) 將快取 30 秒,如果 prefetch prop 設定為 true,則快取 5 分鐘。您可以透過在 next.config.js 中定義自訂的重新驗證時間來覆寫這些預設值

next.config.ts
const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
      static: 180,
    },
  },
};
 
module.exports = nextConfig;

staleTimes 旨在改善目前想要更精細控制快取啟發式的使用者體驗,但它並非完整的解決方案。在即將發布的版本中,我們將專注於改善整體快取語意並提供更靈活的解決方案。

在我們的文件中瞭解更多關於 staleTimes 的資訊。

平行和攔截路由

我們正在持續迭代關於平行攔截路由,現在改善了與用戶端 Router 快取的整合。

  • 呼叫帶有 revalidatePathrevalidateTag 的伺服器動作的平行和攔截路由將重新驗證快取並刷新可見插槽,同時保持使用者目前的視圖。
  • 同樣地,呼叫 router.refresh 現在可以正確地刷新可見插槽,並保持目前的視圖。

錯誤 DX 改進

在 14.1 版本中,我們開始致力於改善執行 next dev 時錯誤訊息和堆疊追蹤的可讀性。這項工作已延續到 14.2 版本,現在包含更好的錯誤訊息、App Router 和 Pages Router 的覆蓋設計改進、淺色和深色模式支援,以及更清晰的 devbuild 日誌。

例如,React Hydration 錯誤是我們社群中常見的混淆來源。雖然我們已進行改進以協助使用者精確找出 hydration 不匹配的來源 (見下文),但我們正與 React 團隊合作,以改善底層錯誤訊息並顯示錯誤發生的檔案名稱。

之前

An example of the Next.js error overlay before version 14.2.
版本 14.2 之前的 Next.js 錯誤覆蓋範例。

之後

An example of the Next.js error overlay after version 14.2.
版本 14.2 之後的 Next.js 錯誤覆蓋範例。

React 19

在二月,React 團隊宣布即將發布 React 19。為了準備 React 19,我們正致力於將最新的功能和改進整合到 Next.js 中,並計劃發布一個主要版本來協調這些變更。

諸如 Actions 及其相關 hooks 等新功能,已從 React canary channel 在 Next.js 中提供,現在將適用於所有 React 應用程式 (包括僅限用戶端的應用程式)。我們很高興看到這些功能在 React 生態系統中獲得更廣泛的採用。

其他改進

  • [文件] 關於影片優化的新文件 (PR)。
  • [文件] 關於 instrumentation.ts 的新文件 (PR)
  • [功能] next/image 的新 overrideSrc prop (PR)。
  • [功能] getStaticProps 的新 revalidateReason 參數 (PR)。
  • [改進] 重構串流邏輯,縮短生產環境中串流頁面的時間 (PR)。
  • [改進] 支援巢狀伺服器動作 (PR)。
  • [改進] 支援在產生的 Sitemap 中進行本地化 (PR)。
  • [改進] 開發和建置日誌的視覺改進 (PR)
  • [改進] Skew protection 在 Vercel 上已穩定 (文件)。
  • [改進] 使 useSelectedLayoutSegment 與 Pages Router 相容 (PR)。
  • [改進] 當絕對 URL 不需要解析時,跳過 metadataBase 警告 (PR)。
  • [改進] 修復部署到 Vercel 時,伺服器動作在未啟用 JavaScript 的情況下無法提交的問題 (PR)
  • [改進] 修復了在從參照頁面導航離開後觸發,或在非活動的平行路由區段內使用時,伺服器動作在動作清單中找不到的錯誤 (PR)
  • [改進] 修復了 next/dynamic 載入的元件中的 CSS 匯入問題 (PR)。
  • [改進] 當動畫圖片缺少 unoptimized prop 時發出警告 (PR)。
  • [改進] 如果 images.loaderFile 未匯出預設函式,則顯示錯誤訊息 (PR)

社群

Next.js 現在擁有超過 100 萬的每月活躍開發人員。我們感謝社群的支持和貢獻。加入 GitHub DiscussionsRedditDiscord 上的對話。

貢獻者

Next.js 是超過 3,000 名個人開發人員、Google 和 Meta 等產業合作夥伴以及我們 Vercel 核心團隊共同努力的成果。此版本由以下人員為您帶來:

非常感謝 @taishikato、@JesseKoldewijn、@Evavic44、@feugy、@liamlaverty、@dvoytenko、@SukkaW、@wbinnssmith、@rishabhpoddar、@better-salmon、@ziyafenn、@A7med3bdulBaset、@jasonuc、@yossydev、@Prachi-meon、@InfiniteCodeMonkeys、@ForsakenHarmony、@miketimmerman、@kwonoj、@williamli、@gnoff、@jsteele-stripe、@chungweileong94、@WITS、@sogoagain、@junioryono、@eisafaqiri、@yannbolliger、@aramikuto、@rocketman-21、@kenji-webdev、@michaelpeterswa、@Dannymx、@vpaflah、@zeevo、@chrisweb、@stefangeneralao、@tknickman、@Kikobeats、@ubinatus、@code-haseeb、@hmmChase、@byhow、@DanielRivers、@wojtekmaj、@paramoshkinandrew、@OMikkel、@theitaliandev、@oliviertassinari、@Ishaan2053、@Sandeep-Mani、@alyahmedaly、@Lezzio、@devjiwonchoi、@juliusmarminge、@szmazhr、@eddiejaoude、@itz-Me-Pj、@AndersDJohnson、@gentamura、@tills13、@dijonmusters、@SaiGanesh21、@vordgi、@ryota-murakami、@tszhong0411、@officialrajdeepsingh、@alexpuertasr、@AkifumiSato、@Jonas-PFX、@icyJoseph、@florian-lp、@pbzona、@erfanium、@remcohaszing、@bernardobelchior、@willashe、@kevinmitch14、@smakosh、@mnjongerius、@asobirov、@theoholl、@suu3、@ArianHamdi、@adrianha、@Sina-Abf、@kuzeykose、@meenie、@nphmuller、@javivelasco、@belgattitude、@Svetoslav99、@johnslemmer、@colbyfayock、@mehranmf31、@m-nakamura145、@ryo8000、@aryaemami59、@bestlyg、@jinsoul75、@petrovmiroslav、@nattui、@zhuyedev、@dongwonnn、@nhducit、@flotwig、@Schmavery、@abhinaypandey02、@rvetere、@coffeecupjapan、@cjimmy、@Soheiljafarnejad、@jantimon、@zengspr、@wesbos、@neomad1337、@MaxLeiter 和 @devr77 等人的協助!