Back返回部落格

Next.js 11.1

Next.js 11.1 帶來了重要的安全性修補、ES Modules 支援、效能提升、基於 Rust 的工具鏈、 預渲染時資料獲取速度提升 2 倍等新功能!

我們透過 Next.js 11.1 全面提升了建置效能,主要包含以下功能:

立即更新請執行 npm i next@latest

安全性修補

Next.js 團隊與安全研究人員和審計人員合作以防止漏洞。我們感謝 Robinhood 的 Gabriel Benmergui 發現 pages/_error.js 的開放式重新導向問題並進行負責任的揭露。

報告的問題不會直接危害用戶,但可能允許從受信任的網域重新導向至攻擊者的網域進行釣魚攻擊。我們已在 Next.js 11.1 中發布修補程式防止此開放式重新導向,並新增了安全性回歸測試

詳情請參閱公開的 CVE。我們建議升級至最新版本的 Next.js 以提高應用程式的整體安全性。未來若有需負責任揭露的報告,請寄送電子郵件至 [email protected]

注意: 託管於 Vercel 的 Next.js 應用程式不受此漏洞影響(因此,在 Vercel 上運行的 Next.js 應用程式無需採取任何行動)。

ES Modules 支援

我們正在 Next.js 中全面支援 ES Modules,包括作為輸入模組和輸出目標。從 Next.js 11.1 開始,您現在可以透過實驗性標誌導入使用 ES Modules 的 npm 套件(例如其 package.json 中包含 "type": "module")。

next.config.js
module.exports = {
  // 優先載入 ES Modules 而非 CommonJS
  experimental: { esmExternals: true },
};

ES Modules 支援包含向後相容性以支援先前的 CommonJS 導入行為。在 Next.js 12 中,esmExternals: true 將成為預設值。我們建議嘗試此新選項並在 GitHub Discussions 中提供反饋以協助改進。

採用基於 Rust 的 SWC

我們正在整合 SWC,這是一個用 Rust 編寫的超快 JavaScript 和 TypeScript 編譯器,將取代 Next.js 中使用的兩個工具鏈:用於單一檔案的 Babel 和用於輸出套件最小化的 Terser。

作為用 SWC 取代 Babel 的一部分,我們正在將 Next.js 使用的所有自訂程式碼轉換移植到用 Rust 編寫的 SWC 轉換中以最大化效能。例如,在 getStaticPropsgetStaticPathsgetServerSideProps 中樹搖未使用的程式碼。

作為用 SWC 取代 Terser 的一部分,我們正在確保 SWC 最小化器的輸出與 Terser 相似,同時大幅提升效能和最小化的平行處理能力。

在早期測試中,使用 Babel 的程式碼轉換時間從 ~500ms 降至 ~10ms,使用 Terser 的程式碼最小化時間從 ~250ms 降至 ~30ms。整體而言,這使得建置速度提升兩倍

我們很高興宣布 SWC 的創建者 DongYoon KangParcel 的貢獻者 Maia Teegarden 已加入 Vercel 的 Next.js 團隊,專注於提升 next devnext build 的效能。我們將在下一版本中分享更多關於 SWC 整合的成果,屆時它將成為穩定功能。

效能提升

建置與資料獲取

當使用 next build 並發出大量 HTTP 請求時,我們已將效能平均提升約 2 倍。例如,如果您使用 getStaticPropsgetStaticPaths 從 Headless CMS 獲取內容,您應該會明顯感受到建置速度的提升。

Next.js 自動填充 node-fetch,現在預設啟用 HTTP Keep-Alive。根據外部基準測試,這應該能使預渲染速度提升約 2 倍

若要為特定 fetch() 呼叫停用 HTTP Keep-Alive,您可以新增 agent 選項:

import { Agent } from 'https';
const url = '<https://example.com>';
const agent = new Agent({ keepAlive: false });
fetch(url, { agent });

若要全域覆蓋所有 fetch() 呼叫,您可以使用 next.config.js

next.config.js
module.exports = {
  httpAgentOptions: {
    keepAlive: false,
  },
};

Source Maps

由於 webpack 資產和 source map 處理的優化,在 Next.js 應用程式中包含瀏覽器 source maps 現在效能成本降低約 70%,記憶體成本降低約 67%。

這僅影響在 next.config.js 檔案中設定 productionBrowserSourceMaps: true 的 Next.js 應用程式。在 Next.js 11.1 中,啟用 source maps 時建置時間僅增加 11%。

我們還與 Sentry 合作提升效能,透過 Sentry Next.js 插件上傳 source maps。

ESLint 改進

在 Next.js 11 中,我們透過 next lint 引入了內建的 ESLint 支援。自初次發布以來,我們持續新增規則以幫助開發者修復應用程式中的常見錯誤。

預設無障礙規則

現在預設包含更好的無障礙規則,防止 ARIA 屬性不匹配和使用不存在的 ARIA 屬性等問題。這些規則預設會發出警告。

特別感謝社群貢獻者 JeffersonBledsoe 新增這些規則。

常見拼寫錯誤

現在預設會對 getStaticPropsgetStaticPathsgetServerSideProps 中的常見拼寫錯誤發出警告。這將幫助解決因小拼寫錯誤導致資料獲取未被呼叫的情況。例如,getstaticpropsgetStaticprops 將顯示警告。

特別感謝社群貢獻者 kaykdm 創建此規則。

next/image 改進

我們收集了社群關於 next/image 和內建圖片優化的反饋,並很高興分享多項關於效能、開發者體驗和使用者體驗的改進。

圖片優化

預設情況下,Next.js 使用 WebAssembly 執行圖片優化,這顯著減少了 Next.js 套件的安裝時間,因為它更小且沒有安裝後步驟。在 Next.js 11.1 中,您可以選擇安裝 sharp,這會優化未快取的圖片生成時間,但代價是較慢的安裝。

基於 WebAssembly 的圖片優化器已更新以支援 ARM 晶片(如 Apple M1)與 Node.js 16。

內建的圖片優化器現在會根據回應主體的內容自動偵測外部圖片的內容類型。這使得 Next.js 能夠優化託管在 AWS S3 上的圖片,即使回應標頭為 Content-Type: application/octet-stream

開發環境中延遲生成模糊佔位圖

next dev 期間,帶有 placeholder="blur"靜態圖片導入現在會自動延遲生成,從而提升具有大量靜態圖片導入的開發伺服器啟動時間:

pages/index.js
import Image from 'next/image';
import author from '../public/me.png';
 
export default function Home() {
  return (
    // 此圖片的佔位圖在開發環境中會延遲生成
    <Image src={author} alt="作者圖片" placeholder="blur" />
  );
}

其他圖片改進

  • 先前載入過的圖片不再延遲載入:當圖片先前已在頁面上載入過(無論是透過客戶端導航或在頁面其他位置載入),Next.js 現在會自動跳過延遲載入以避免在顯示圖片前出現快速閃爍。
  • 支援 next export 與自訂圖片載入器next/image 現在支援使用 next export 與任何第三方圖片優化服務。當您打算為 next/image 提供自訂 loader 屬性時,可以在 next.config.js 中設定 images.loader: "custom"
  • 新增圖片載入完成事件:根據用戶反饋,我們為 next/image 新增了一個新屬性 onLoadingComplete。這允許註冊一個在圖片完全載入後被呼叫的回呼函式。
  • 設定預設圖片快取 TTL(存活時間):您現在可以在 next.config.js 中設定 images.minimumCacheTTL 來變更優化圖片的預設快取 TTL。在可能的情況下,我們建議使用靜態圖片 import,因為這些圖片會自動使用最大 TTL,因為圖片內容雜湊值包含在 URL 中。

社群

Next.js 是超過 1,700 名獨立開發者、Google 和 Facebook 等產業合作夥伴以及我們核心團隊共同努力的成果。

我們很自豪地看到社群持續成長。僅在過去六個月內,我們就看到 Next.js 在 NPM 上的下載量從 410 萬增加到 620 萬,成長了 50%,並且在 Alexa 前 10,000 名網站中使用 Next.js 的首頁數量也成長了 50%。

此版本由以下貢獻者共同完成:@abotsi, @adam-cowley, @afbarbaro, @akellbl4, @AndreVarandas, @andys-github, @angeloashmore, @apuyou, @arturmuller, @AryanBeezadhur, @atcastle, @borekb, @brandonchinn178, @breyed, @brijendravarma, @ctbarna, @ctjlewis, @darshkpatel, @delbaoliveira, @destruc7i0n, @devknoll, @enesakar, @enzoferey, @euess, @fabb, @gnbaron, @hiro0218, @housseindjirdeh, @huozhi, @ijjk, @JacobLey, @jameshoward, @jamsinclair, @janicklas-ralph, @jarvelov, @javivelasco, @jaybekster, @JeffersonBledsoe, @jflayhart, @johnrackles, @jviide, @karlsander, @kasipavankumar, @kaykdm, @kdy1, @kylemh, @leerob, @LetItRock, @lsndr, @lucleray, @m-abdelwahab, @mandarons, @markkaylor, @mastoj, @michalbundyra, @michielvangendt, @Munawwar, @mvasilkov, @NickCrews, @NickKelly1, @noahweingand, @noreiller, @nyedidikeke, @omasher, @orta, @pa-rang, @padmaia, @papaponmx, @PaulvdDool, @petermekhaeil, @phocks, @pranavp10, @qwertyforce, @raon0211, @reod, @rishabhpoddar, @roim, @Ryz0nd, @sa3dany, @sachinraja, @samrobbins85, @schoenwaldnils, @schultzp2020, @sedlukha, @sergioalvz, @shibe23, @smitssjors, @sohamsshah, @sokra, @stefanprobst, @stovmascript, @stuymedova, @styfle, @tanys123, @ThangHuuVu, @theostrahlen, @thomasmarshall, @tigger9flow, @timneutkens, @Timvdv, @tmcgann, @tomchen, @UniqueNL, @Vadorequest, @vitalybaev, @yunger7, @zackdotcomputer, @zeekrey