Next.js 14 正式發(fā)布,更快、更強、更可靠!你Get到了嗎?
10 月 26 日,Next.js 正式發(fā)布。該版本的主要更新如下:
- Turbopack:App & Pages Router 通過 5000 個測試
本地服務(wù)器啟動速度提高了 53%
通過快速刷新,代碼更新速度提高 94%
- 服務(wù)端操作(穩(wěn)定):逐步增強的數(shù)據(jù)變更
- 集成了緩存和重新驗證
- 簡單的函數(shù)調(diào)用,或者與表單原生配合工作
- 部分預渲染(預覽):快速的初始靜態(tài)響應(yīng) + 流式動態(tài)內(nèi)容
- Next.js Learn(全新):教授 App Router、身份驗證、數(shù)據(jù)庫等內(nèi)容的免費課程。
可以通過以下命令來立即升級最新版本:
npx create-next-app@latest
Next.js 編譯器
自 Next.js 13 以來,Next 團隊一直致力于提高 Next.js 中 Pages 和 App Router 的本地開發(fā)性能。
之前,Next 團隊通過重寫 Next.js 的 next dev 和其他部分以實現(xiàn)這一目標。然而,后來改變了方法,采取了更漸進的方式?,F(xiàn)在,重點是首先支持所有 Next.js 的功能,因此基于 Rust 的編譯器很快就會穩(wěn)定下來。
Next.js 使用基于 Rust 引擎的 Turbopack,現(xiàn)在已經(jīng)通過了 5000 個 next dev 的集成測試。這些測試涵蓋了過去 7 年中的錯誤修復和重現(xiàn)。
在大型 Next.js 應(yīng)用 vercel.com 上進行測試時,可以看到:
- 本地服務(wù)器啟動速度提高高達 53.3%
- 通過快速刷新,代碼更新速度提高高達 94.7%
該基準測試是大型應(yīng)用(和大型模塊圖)性能改進的實際結(jié)果?,F(xiàn)在,next dev 的 90% 測試已經(jīng)通過,在使用 next dev --turbo 時,應(yīng)該會看到更快、更可靠的性能表現(xiàn)。
一旦達到 100% 的測試通過,將在即將發(fā)布的次要版本中將 Turbopack 移至穩(wěn)定版本。另外,還將繼續(xù)支持使用 webpack 進行自定義配置和生態(tài)系統(tǒng)插件。
可以在 areweturboyet.com 上關(guān)注通過測試的百分比。
表單和數(shù)據(jù)變更
Next.js 9 引入了 API Routes,這是一種快速構(gòu)建后端端點的方法,可以與前端代碼一起使用。
例如,可以在 api/ 目錄中創(chuàng)建一個新文件:
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const data = req.body;
const id = await createItem(data);
res.status(200).json({ id });
}
然后,在客戶端,可以使用 React 和 onSubmit 等事件處理程序來獲取 API 路由:
import { FormEvent } from 'react';
export default function Page() {
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
});
// Handle response if necessary
const data = await response.json();
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
現(xiàn)在,隨著 Next.js 14 的推出,希望簡化開發(fā)者在編寫數(shù)據(jù)變更時的體驗。此外,還希望在用戶網(wǎng)絡(luò)連接較慢或從低功率設(shè)備提交表單時改善用戶體驗。
服務(wù)端操作(穩(wěn)定)
如果不想手動創(chuàng)建 API Route,那么可以定義一個函數(shù),在服務(wù)端安全地運行,并直接從 React 組件中調(diào)用它。
App Router 構(gòu)建在 React canary 通道上,對于框架 采用新功能來說是穩(wěn)定的。從 v14 開始,Next.js 已升級到最新的 React canary,其中包括穩(wěn)定的服務(wù)器操作。
App Router 是建立在 React canary 通道上的,這個通道對于框架來采用新功能是穩(wěn)定的。從 v14 開始,Next.js 已經(jīng)升級到了最新的 React canary 版本,其中包含穩(wěn)定的服務(wù)端操作功能。
前面 Pages Router 的例子可以簡化為一個文件:
export default function Page() {
async function create(formData: FormData) {
'use server';
const id = await createItem(formData);
}
return (
<form action={create}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
服務(wù)端操作對于之前使用過服務(wù)端中心框架的開發(fā)者來說應(yīng)該會很熟悉。它是建立在 Web 基礎(chǔ)知識(如表單和 FormData Web API)之上的。
通過表單使用服務(wù)端操作對于漸進增強是有幫助的,但并不是必需的。也可以直接將其作為函數(shù)調(diào)用,而無需使用表單。在使用 TypeScript 時,這提供了完整的端到端類型安全性,確??蛻舳撕头?wù)端之間的安全性。
數(shù)據(jù)變更、頁面重新渲染或重定向可以在一次網(wǎng)絡(luò)往返中完成,確保在客戶端上顯示正確的數(shù)據(jù),即使上游提供者的響應(yīng)速度較慢。此外,可以組合和重用不同的操作,包括在同一個路由中使用多個不同的操作。
緩存、重新驗證、重定向等
服務(wù)端操作深度集成到整個 App Router 模型中。你可以:
- 使用 revalidatePath() 或 revalidateTag() 可以重新驗證緩存的數(shù)據(jù)。
- 使用redirect()重定向到不同的路由。
- 使用cookies()設(shè)置和讀取cookie
- 使用 useOptimistic() 處理樂觀 UI 更新
- 使用 useFormState() 捕獲并顯示來自服務(wù)端的錯誤
- 使用 useFormStatus() 在客戶端顯示加載狀態(tài)
部分預渲染(預覽)
Next.js 中正在開發(fā)的部分預渲染推出了預覽版,它是一種針對動態(tài)內(nèi)容的編譯器優(yōu)化,可以實現(xiàn)快速的初始靜態(tài)響應(yīng)。
部分預渲染建立在對服務(wù)端渲染(SSR)、靜態(tài)站點生成(SSG)和增量靜態(tài)重新驗證(ISR)進行了十年的研究和開發(fā)的基礎(chǔ)上。
動機
目前存在過多的運行時、配置選項和渲染方法需要考慮。希望在享受靜態(tài)網(wǎng)頁的速度和可靠性的同時,也能支持完全動態(tài)、個性化的響應(yīng)。不過,擁有出色的性能和個性化體驗不應(yīng)以復雜性為代價。
面臨的挑戰(zhàn)是創(chuàng)建更好的開發(fā)體驗,簡化現(xiàn)有模型,而無需引入新的需要學習的 API。雖然部分緩存服務(wù)端內(nèi)容的方法已經(jīng)存在,但這些方法仍然需要滿足旨在實現(xiàn)的開發(fā)者體驗和可組合性目標。
部分預渲染不需要學習新的 API。
建立在 React Suspense 之上
部分預渲染是由 Suspense 邊界定義的。以下是它的工作原理。考慮以下電子商務(wù)頁面:
export default function Page() {
return (
<main>
<header>
<h1>My Store</h1>
<Suspense fallback={<CartSkeleton />}>
<ShoppingCart />
</Suspense>
</header>
<Banner />
<Suspense fallback={<ProductListSkeleton />}>
<Recommendations />
</Suspense>
<NewProducts />
</main>
);
}
啟用部分預渲染后,該頁面將根據(jù) <Suspense /> 邊界生成靜態(tài)骨架,它包含了頁面的結(jié)構(gòu)和布局,但不包含動態(tài)內(nèi)容。React Suspense 的fallback也會被預渲染。
然后,在靜態(tài)骨架中,Suspense 的fallback將被動態(tài)組件替換,例如讀取 cookie 來確定購物車內(nèi)容,或者根據(jù)用戶顯示橫幅廣告。
當發(fā)出請求時,立即提供靜態(tài) HTML 骨架:
<main>
<header>
<h1>My Store</h1>
<div class="cart-skeleton">
<!-- Hole -->
</div>
</header>
<div class="banner" />
<div class="product-list-skeleton">
<!-- Hole -->
</div>
<section class="new-products" />
</main>
由于 <ShoppingCart /> 組件需要讀取cookie以查看用戶會話,因此該組件將作為同一HTTP請求的一部分進行流式傳輸,與靜態(tài)骨架一起加載,這樣就不需要額外的網(wǎng)絡(luò)往返。
import { cookies } from 'next/headers'
export default function ShoppingCart() {
const cookieStore = cookies()
const session = cookieStore.get('session')
return ...
}
為了獲得最細粒度的靜態(tài)骨架,可能需要添加額外的 <Suspense /> 邊界。然而,如果今天已經(jīng)在使用 loading.js,那么這是一個隱式的 <Suspense /> 邊界,因此不需要更改即可生成靜態(tài)骨架。
即將到來
部分預渲染正在積極開發(fā)中,將在即將發(fā)布的次要版本中分享更多更新。
元數(shù)據(jù)改進
在頁面內(nèi)容從服務(wù)端流式傳輸之前,需要先向瀏覽器發(fā)送關(guān)于視口、顏色方案和主題等重要元數(shù)據(jù)。
確保這些meta標簽與初始頁面內(nèi)容一起發(fā)送可以提供流暢的用戶體驗,防止由于更改主題顏色或視口變化而導致頁面閃爍或布局偏移。
在 Next.js 14 中,將阻塞和非阻塞的元數(shù)據(jù)解耦。只有一小部分元數(shù)據(jù)選項是阻塞的,希望確保非阻塞的元數(shù)據(jù)不會阻止部分預渲染頁面提供靜態(tài)骨架。
以下元數(shù)據(jù)選項現(xiàn)已棄用,并將在未來的主要版本中從元數(shù)據(jù)中刪除:
- viewport:設(shè)置視口的初始縮放和其他屬性
- colorScheme:設(shè)置視口的支持模式(亮/暗)
- themeColor: 設(shè)置視口周圍的瀏覽器界面應(yīng)該呈現(xiàn)的顏色
從 Next.js 14 開始,使用新的選項 viewport 和 generateViewport 來替換這些選項。所有其他元數(shù)據(jù)選項保持不變。
Next.js Learn 課程
在 Next.js Learn 上發(fā)布了全新的免費課程。本課程教授:
- Next.js App Router
- 樣式和 Tailwind CSS
- 優(yōu)化字體和圖像
- 創(chuàng)建布局和頁面
- 在頁面之間導航
- 設(shè)置 Postgres 數(shù)據(jù)庫
- 使用服務(wù)端組件獲取數(shù)據(jù)
- 靜態(tài)和動態(tài)渲染
- 流媒體
- 部分預渲染(可選)
- 添加搜索和分頁
- 數(shù)據(jù)變更
- 錯誤處理
- 改善無障礙環(huán)境
- 添加身份驗證
- 添加元數(shù)據(jù)
其他更新
- [重大變更] 現(xiàn)在 Node.js 最低版本要求為 18.17
- [重大變更] 移除了 next-swc 構(gòu)建的 WASM 目標
- [重大變更] 放棄支持 @next/font,轉(zhuǎn)而支持 next/font
- [重大變更] 將 ImageResponse 導入從 next/server 更改為 next/og
- [重大變更] next export 命令已棄用,推薦使用 output: 'export'
- [棄用] next/image 的 onLoadingComplete 已棄用,推薦使用 onLoad
- [棄用] next/image 的 domains 已棄用,推薦使用 remotePatterns
- [功能] 可以啟用更詳細的關(guān)于獲取緩存的日志記錄
- [改進] 基本 create-next-app 應(yīng)用的函數(shù)大小減小了 80%