Back返回博客

Next.js 14

Next.js 14 包含服务端操作 (Server Actions) 的性能提升与稳定性改进、全新的应用路由 (App Router) 教学课程等更新。

正如我们在 Next.js 大会 上宣布的,Next.js 14 是我们最专注的版本,包含以下特性:

立即升级或通过以下命令开始使用:

终端
npx create-next-app@latest

Next.js 编译器:涡轮加速

自 Next.js 13 起,我们持续优化页面路由和应用路由的本地开发性能。

此前,我们重写了 next dev 和其他核心模块来支持这项工作。现在我们调整为更渐进式的改进策略,这意味着基于 Rust 的编译器将在全面支持 Next.js 所有功能后很快进入稳定阶段。

通过底层 Rust 引擎 Turbopacknext dev 现已通过 5,000 项集成测试,这些测试包含 7 年来的错误修复案例。

在大型 Next.js 应用 vercel.com 上的测试结果显示:

  • 本地服务器启动速度最高提升 53.3%
  • 代码更新时的热刷新速度最高提升 94.7%

这些基准测试反映了大型应用(及复杂模块图)的实际性能提升。目前 next dev 90% 的测试已通过,使用 next dev --turbo 时您将获得更快速稳定的开发体验。

当测试通过率达到 100% 时,我们将在后续的小版本中发布 Turbopack 稳定版。同时将继续支持 webpack 以满足自定义配置和生态插件需求。

您可以通过 areweturboyet.com 追踪测试通过进度。

表单与数据变更

Next.js 9 引入了 API 路由 (API Routes)——一种在前端代码旁快速构建后端端点的方式。

例如,在 api/ 目录创建文件:

pages/api/submit.ts
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 路由发起请求:

pages/index.tsx
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,
    });
 
    // 如需处理响应
    const data = await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">提交</button>
    </form>
  );
}

Next.js 14 进一步简化了数据变更的开发体验,并优化了慢速网络或低功耗设备下的表单提交体验。

服务端操作 (Server Actions)(稳定版)

现在您无需手动创建 API 路由,只需定义可在服务端安全执行的函数,并直接从 React 组件调用:

app/page.tsx
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">提交</button>
    </form>
  );
}

服务端操作基于 FormData Web API 等网络基础能力构建。除了表单提交,您也可以直接调用这些函数(配合 TypeScript 可实现客户端与服务端的全链路类型安全)。

数据变更、页面重渲染或重定向可在单次网络往返中完成,确保客户端始终显示正确数据。您还可以组合复用多个操作。

缓存、重新验证、重定向等

服务端操作深度集成于应用路由模型,支持:

  • 通过 revalidatePath()revalidateTag() 重新验证缓存
  • 通过 redirect() 跳转路由
  • 通过 cookies() 读写 Cookie
  • 使用 useOptimistic() 实现乐观 UI 更新
  • 通过 useFormState() 捕获服务端错误
  • 使用 useFormStatus() 显示加载状态

了解更多关于服务端操作的表单与数据变更安全模型的最佳实践。

部分预渲染 (Partial Prerendering)(预览版)

我们正在为 Next.js 开发部分预渲染功能——通过编译器优化实现动态内容的快速静态初始响应。

该功能基于服务端渲染 (SSR)、静态生成 (SSG) 和增量静态再生 (ISR) 十年的技术积累。

设计初衷

我们注意到现有渲染方案存在过多运行时和配置选项。开发者既需要静态化的速度与可靠性,又希望支持全动态个性化响应。

优秀的全球性能与个性化不应以复杂性为代价。

部分预渲染无需学习新 API,通过 React Suspense 边界自动识别静态与动态内容。例如电商页面:

app/page.tsx
export default function Page() {
  return (
    <main>
      <header>
        <h1>我的商店</h1>
        <Suspense fallback={<CartSkeleton />}>
          <ShoppingCart />
        </Suspense>
      </header>
      <Banner />
      <Suspense fallback={<ProductListSkeleton />}>
        <Recommendations />
      </Suspense>
      <NewProducts />
    </main>
  );
}

启用后,该页面会基于 Suspense 边界生成静态外壳,动态内容(如读取 Cookie 的购物车组件)将在同一 HTTP 请求中流式传输。如果您已使用 loading.js,这些隐式 Suspense 边界将自动用于生成静态外壳。

即将推出

部分预渲染功能正在积极开发中。我们将在接下来的小版本中分享更多更新。

元数据改进

在页面内容从服务器流式传输之前,需要先将视口、配色方案和主题等重要元数据发送至浏览器。

确保这些 meta 标签随初始页面内容一同发送,有助于提供流畅的用户体验,避免因主题色变更导致的页面闪烁,或视口变化引发的布局偏移。

在 Next.js 14 中,我们解耦了阻塞型与非阻塞型元数据。现在只有少量元数据选项属于阻塞型,同时我们确保非阻塞型元数据不会阻碍部分预渲染页面提供静态外壳。

以下元数据选项现已弃用,并将在未来的主版本中从 metadata 移除:

  • viewport:设置视口的初始缩放等属性
  • colorScheme:设置视口支持的模式(浅色/深色)
  • themeColor:设置视口周围浏览器边框的渲染颜色

从 Next.js 14 开始,新增了 viewportgenerateViewport 选项来替代上述功能。其他所有 metadata 选项保持不变。

您现在就可以开始采用这些新 API,现有 metadata 选项仍可继续使用。

Next.js 学习课程

今天我们发布了全新的免费课程 Next.js Learn,内容包括:

  • Next.js App Router
  • 样式与 Tailwind CSS
  • 优化字体与图片
  • 创建布局与页面
  • 页面间导航
  • 配置 Postgres 数据库
  • 使用服务端组件获取数据
  • 静态与动态渲染
  • 流式传输
  • 部分预渲染(可选)
  • 添加搜索与分页
  • 数据变更
  • 错误处理
  • 提升可访问性
  • 添加身份验证
  • 添加元数据

Next.js Learn 已为数百万开发者传授了框架基础知识,我们期待您对新课程的反馈。立即访问 nextjs.org/learn 开始学习。

其他变更

  • 【重大变更】 最低 Node.js 版本要求提升至 18.17
  • 【重大变更】 移除 next-swc 的 WASM 构建目标(PR
  • 【重大变更】 弃用 @next/font,全面转向 next/font代码迁移工具
  • 【重大变更】ImageResponse 的导入路径从 next/server 改为 next/og代码迁移工具
  • 【重大变更】 移除 next export 命令,改用 output: 'export' 配置(文档
  • 【弃用通知】 next/imageonLoadingComplete 被弃用,推荐使用 onLoad
  • 【弃用通知】 next/imagedomains 被弃用,推荐使用 remotePatterns
  • 【新功能】 可启用更详细的 fetch 缓存日志(文档
  • 【优化】 基础 create-next-app 应用体积减少 80%
  • 【优化】 开发环境下使用 edge 运行时时的内存管理增强

贡献者

Next.js 是 2,900 多位独立开发者、Google 和 Meta 等行业合作伙伴以及 Vercel 核心团队共同协作的成果。欢迎通过 GitHub DiscussionsRedditDiscord 加入社区。

本版本由以下成员共同打造:

以及以下贡献者:@05lazy、@0xadada、@2-NOW、@aarnadlr、@aaronbrown-vercel、@aaronjy、@abayomi185、@abe1272001、@abhiyandhakal、@abstractvector、@acdlite、@adamjmcgrath、@AdamKatzDev、@adamrhunter、@ademilter、@adictonator、@adilansari、@adtc、@afonsojramos、@agadzik、@agrattan0820、@akd-io、@AkifumiSato、@akshaynox、@alainkaiser、@alantoa、@albertothedev、@AldeonMoriak、@aleksa-codes、@alexanderbluhm、@alexkirsz、@alfred-mountfield、@alpha-xek、@andarist、@Andarist、@andrii-bodnar、@andykenward、@angel1254mc、@anonrig、@anthonyshew、@AntoineBourin、@anujssstw、@apeltop、@aralroca、@aretrace、@artdevgame、@artechventure、@arturbien、@Aryan9592、@AviAvinav、@aziyatali、@BaffinLee、@Banbarashik、@bencmbrook、@benjie、@bennettdams、@bertho-zero、@bigyanse、@Bitbbot、@blue-devil1134、@bot08、@bottxiang、@Bowens20832、@bre30kra69cs、@BrennanColberg、@brkalow、@BrodaNoel、@Brooooooklyn、@brunoeduardodev、@brvnonascimento、@carlos-menezes、@cassidoo、@cattmote、@cesarkohl、@chanceaclark、@charkour、@charlesbdudley、@chibicode、@chrisipanaque、@ChristianIvicevic、@chriswdmr、@chunsch、@ciruz、@cjmling、@clive-h-townsend、@colinhacks、@colinking、@coreyleelarson、@Cow258、@cprussin、@craigwheeler、@cramforce、@cravend、@cristobaldominguez95、@ctjlewis、@cvolant、@cxa、@danger-ahead、@daniel-web-developer、@danmindru、@dante-robinson、@darshanjain-entrepreneur、@darshkpatel、@davecarlson、@David0z、@davidnx、@dciug、@delbaoliveira、@denchance、@DerTimonius、@devagrawal09、@DevEsteves、@devjiwonchoi、@devknoll、@DevLab2425、@devvspaces、@didemkkaslan、@dijonmusters、@dirheimerb、@djreillo、@dlehmhus、@doinki、@dpnolte、@Drblessing、@dtinth、@ducanhgh、@DuCanhGH、@ductnn、@duncanogle、@dunklesToast、@DustinsCode、@dvakatsiienko、@dvoytenko、@dylanjha、@ecklf、@EndangeredMassa、@eps1lon、@ericfennis、@escwxyz、@Ethan-Arrowood、@ethanmick、@ethomson、@fantaasm、@feikerwu、@ferdingler、@FernandVEYRIER、@feugy、@fgiuliani、@fomichroman、@Fonger、@ForsakenHarmony、@franktronics、@FSaldanha、@fsansalvadore、@furkanmavili、@g12i、@gabschne、@gaojude、@gdborton、@gergelyke、@gfgabrielfranca、@gidgudgod、@Gladowar、@Gnadhi、@gnoff、@goguda、@greatSumini、@gruz0、@Guilleo03、@gustavostz、@hanneslund、@HarshaVardhanReddyDuvvuru、@haschikeks、@Heidar-An、@heyitsuzair、@hiddenest、@hiro0218、@hotters、@hsrvms、@hu0p、@hughlilly、@HurSungYun、@hustLer2k、@iamarpitpatidar、@ianldgs、@ianmacartney、@iaurg、@ibash、@ibrahemid、@idoob、@iiegor、@ikryvorotenko、@imranbarbhuiya、@ingovals、@inokawa、@insik-han、@isaackatayev、@ishaqibrahimbot、@ismaelrumzan、@itsmingjie、@ivanhofer、@IvanKiral、@jacobsfletch、@jakemstar、@jamespearson、@JanCizmar、@janicklas-ralph、@jankaifer、@JanKaifer、@jantimon、@jaredpalmer、@javivelasco、@jayair、@jaykch、@Jeffrey-Zutt、@jenewland1999、@jeremydouglas、@JesseKoldewijn、@jessewarren-aa、@jimcresswell、@jiwooIncludeJeong、@jocarrd、@joefreeman、@JohnAdib、@JohnAlbin、@JohnDaly、@johnnyomair、@johnta0、@joliss、@jomeswang、@joostdecock、@Josehower、@josephcsoti、@josh、@joshuabaker、@JoshuaKGoldberg、@joshuaslate、@joulev、@jsteele-stripe、@JTaylor0196、@JuanM04、@jueungrace、@juliusmarminge、@Juneezee、@Just-Moh-it、@juzhiyuan、@jyunhanlin、@kaguya3222、@karlhorky、@kevinmitch14、@keyz、@kijikunnn、@kikobeats、@Kikobeats、@kleintorres、@koba04、@koenpunt、@koltong、@konomae、@kosai106、@krmeda、@kvnang、@kwonoj、@ky1ejs、@kylemcd、@labyrinthitis、@lachlanjc、@lacymorrow、@laityned、@Lantianyou、@leerob、@leodr、@leoortizz、@li-jia-nan、@loettz、@lorenzobloedow、@lubakravche、@lucasassisrosa、@lucasconstantino、@lucgagan、@LukeSchlangen、@LuudJanssen、@lycuid、@M3kH、@m7yue、@manovotny、@maranomynet、@marcus-rise、@MarDi66、@MarkAtOmniux、@martin-wahlberg、@masnormen、@matepapp、@matthew-heath、@mattpr、@maxleiter、@MaxLeiter、@maxproske、@meenie、@meesvandongen、@mhmdrioaf、@michaeloliverx、@mike-plummer、@MiLk、@milovangudelj、@Mingyu-Song、@mirismaili、@mkcy3、@mknichel、@mltsy、@mmaaaaz、@mnajdova、@moetazaneta、@mohanraj-r、@molebox、@morganfeeney、@motopods、@mPaella、@mrkldshv、@mrxbox98、@nabsul、@nathanhammond、@nbouvrette、@nekochantaiwan、@nfinished、@Nick-Mazuk、@nickmccurdy、@niedziolkamichal、@niko20、@nikolovlazar、@nivak-monarch、@nk980113、@nnnnoel、@nocell、@notrab、@nroland013、@nuta、@nutlope、@obusk、@okcoker、@oliviertassinari、@omarhoumz、@opnay、@orionmiz、@ossan-engineer、@patrick91、@pauek、@peraltafederico、@Phiction、@pn-code、@pyjun01、@pythagoras-yamamoto、@qrohlf、@raisedadead、@reconbot、@reshmi-sriram、@reyrodrigez、@ricardofiorani、@rightones、@riqwan、@rishabhpoddar、@rjsdnql123、@rodrigofeijao、@runjuu、@Ryan-Dia、@ryo-manba、@s0h311、@sagarpreet-xflowpay、@sairajchouhan、@samdenty、@samsisle、@sanjaiyan-dev、@saseungmin、@SCG82、@schehata、@Schniz、@sepiropht、@serkanbektas、@sferadev、@ShaunFerris、@shivanshubisht、@shozibabbas、@silvioprog、@simonswiss、@simPod、@sivtu、@SleeplessOne1917、@smaeda-ks、@sonam-serchan、@SonMooSans、@soonoo、@sophiebits、@souporserious、@sp00ls、@sqve、@sreetamdas、@stafyniaksacha、@starunaway、@steebchen、@stefanprobst、@steppefox、@steven-tey、@suhaotian、@sukkaw、@SukkaW、@superbahbi、@SuttonJack、@svarunid、@swaminator、@swarnava、@syedtaqi95、@taep96、@taylorbryant、@teobler、@Terro216、@theevilhead、@thepatrick00、@therealrinku、@thomasballinger、@thorwebdev、@tibi1220、@tim-hanssen、@timeyoutakeit、@tka5、@tknickman、@tomryanx、@trigaten、@tristndev、@tunamagur0、@tvthatsme、@tyhopp、@tyler-lutz、@UnknownMonk、@v1k1、@valentincostam、@valentinh、@valentinpolitov、@vamcs、@vasucp1207、@vicsantizo、@vinaykulk621、@vincenthongzy、@visshaljagtap、@vladikoff、@wherehows、@WhoAmIRUS、@WilderDev、@Willem-Jaap、@williamli、@wiredacorn、@wiscaksono、@wojtekolek、@ws-jm、@wxh06、@wyattfry、@wyattjoh、@xiaolou86、@y-tsubuku、@yagogmaisp、@yangshun、@yasath、@Yash-Singh1、@yigithanyucedag、@ykzts、@Yovach、@yutsuten、@yyuemii、@zek、@zekicaneksi、@zignis 和 @zlrlyy