【资讯】1851- Next.js 14 正式发布,更快、更强、更可靠!

2023-11-03 16:17:12 浏览数 (1)

Turbopack:App & Pages Router 通过 5000 个测试

  • 本地服务器启动速度提高了 53%
  • 通过快速刷新,代码更新速度提高 94%

  • 服务端操作(稳定):逐步增强的数据变更
    • 集成了缓存和重新验证
    • 简单的函数调用,或者与表单原生配合工作
  • 部分预渲染(预览):快速的初始静态响应 流式动态内容
  • Next.js Learn(全新):教授 App Router、身份验证、数据库等内容的免费课程。

可以通过以下命令来立即升级最新版本:

代码语言:javascript复制
 
npx create-next-app@latest

Next.js 编译器

自 Next.js 13 以来,Next 团队一直致力于提高 Next.js 中 Pages 和 App Router 的本地开发性能。

之前,Next 团队通过重写 Next.js 的 next dev 和其他部分以实现这一目标。然而,后来改变了方法,采取了更渐进的方式。现在,重点是首先支持所有 Next.js 的功能,因此基于 Rust 的编译器很快就会稳定下来。

Next.js 使用基于 Rust 引擎的 Turbopack,现在已经通过了 5000 个 next dev 的集成测试。这些测试涵盖了过去 7 年中的错误修复和重现。

在大型 Next.js 应用 vercel.com 上进行测试时,可以看到:

  • 本地服务器启动速度提高高达 53.3%
  • 通过快速刷新,代码更新速度提高高达 94.7%

该基准测试是大型应用(和大型模块图)性能改进的实际结果。现在,next dev 的 90% 测试已经通过,在使用 next dev --turbo 时,应该会看到更快、更可靠的性能表现。

一旦达到 100% 的测试通过,将在即将发布的次要版本中将 Turbopack 移至稳定版本。另外,还将继续支持使用 webpack 进行自定义配置和生态系统插件。

可以在 areweturboyet.com 上关注通过测试的百分比。

表单和数据变更

Next.js 9 引入了 API Routes,这是一种快速构建后端端点的方法,可以与前端代码一起使用。

例如,可以在 api/ 目录中创建一个新文件:

代码语言:javascript复制
 
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 路由:

代码语言:javascript复制
 
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>
  );
}

现在,随着 Next.js 14 的推出,希望简化开发者在编写数据变更时的体验。此外,还希望在用户网络连接较慢或从低功率设备提交表单时改善用户体验。

服务端操作(稳定)

如果不想手动创建 API Route,那么可以定义一个函数,在服务端安全地运行,并直接从 React 组件中调用它。

App Router 构建在 React canary 通道上,对于框架 采用新功能来说是稳定的。从 v14 开始,Next.js 已升级到最新的 React canary,其中包括稳定的服务器操作。

App Router 是建立在 React canary 通道上的,这个通道对于框架来采用新功能是稳定的。从 v14 开始,Next.js 已经升级到了最新的 React canary 版本,其中包含稳定的服务端操作功能。

前面 Pages Router 的例子可以简化为一个文件:

代码语言:javascript复制
 
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>
  );
}

服务端操作对于之前使用过服务端中心框架的开发者来说应该会很熟悉。它是建立在 Web 基础知识(如表单和 FormData Web API)之上的。

通过表单使用服务端操作对于渐进增强是有帮助的,但并不是必需的。也可以直接将其作为函数调用,而无需使用表单。在使用 TypeScript 时,这提供了完整的端到端类型安全性,确保客户端和服务端之间的安全性。

数据变更、页面重新渲染或重定向可以在一次网络往返中完成,确保在客户端上显示正确的数据,即使上游提供者的响应速度较慢。此外,可以组合和重用不同的操作,包括在同一个路由中使用多个不同的操作。

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

服务端操作深度集成到整个 App Router 模型中。你可以:

  • 使用 revalidatePath()revalidateTag() 可以重新验证缓存的数据。
  • 使用redirect()重定向到不同的路由。
  • 使用cookies()设置和读取cookie
  • 使用 useOptimistic() 处理乐观 UI 更新
  • 使用 useFormState() 捕获并显示来自服务端的错误
  • 使用 useFormStatus() 在客户端显示加载状态

部分预渲染(预览)

Next.js 中正在开发的部分预渲染推出了预览版,它是一种针对动态内容的编译器优化,可以实现快速的初始静态响应。

部分预渲染建立在对服务端渲染(SSR)、静态站点生成(SSG)和增量静态重新验证(ISR)进行了十年的研究和开发的基础上。

动机

目前存在过多的运行时、配置选项和渲染方法需要考虑。希望在享受静态网页的速度和可靠性的同时,也能支持完全动态、个性化的响应。不过,拥有出色的性能和个性化体验不应以复杂性为代价。

面临的挑战是创建更好的开发体验,简化现有模型,而无需引入新的需要学习的 API。虽然部分缓存服务端内容的方法已经存在,但这些方法仍然需要满足旨在实现的开发者体验和可组合性目标。

部分预渲染不需要学习新的 API。

建立在 React Suspense 之上

部分预渲染是由 Suspense 边界定义的。以下是它的工作原理。考虑以下电子商务页面:

代码语言:javascript复制
 
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>
  );
}

启用部分预渲染后,该页面将根据 <Suspense /> 边界生成静态骨架,它包含了页面的结构和布局,但不包含动态内容。React Suspense 的fallback也会被预渲染。

然后,在静态骨架中,Suspense 的fallback将被动态组件替换,例如读取 cookie 来确定购物车内容,或者根据用户显示横幅广告。

当发出请求时,立即提供静态 HTML 骨架:

代码语言:javascript复制
 
<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请求的一部分进行流式传输,与静态骨架一起加载,这样就不需要额外的网络往返。

代码语言:javascript复制
 
import { cookies } from 'next/headers'

export default function ShoppingCart() {
  const cookieStore = cookies()
  const session = cookieStore.get('session')
  return ...
}

为了获得最细粒度的静态骨架,可能需要添加额外的 <Suspense /> 边界。然而,如果今天已经在使用 loading.js,那么这是一个隐式的 <Suspense /> 边界,因此不需要更改即可生成静态骨架。

即将到来

部分预渲染正在积极开发中,将在即将发布的次要版本中分享更多更新。

元数据改进

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

确保这些meta标签与初始页面内容一起发送可以提供流畅的用户体验,防止由于更改主题颜色或视口变化而导致页面闪烁或布局偏移。

在 Next.js 14 中,将阻塞和非阻塞的元数据解耦。只有一小部分元数据选项是阻塞的,希望确保非阻塞的元数据不会阻止部分预渲染页面提供静态骨架。

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

  • viewport:设置视口的初始缩放和其他属性
  • colorScheme:设置视口的支持模式(亮/暗)
  • themeColor: 设置视口周围的浏览器界面应该呈现的颜色

从 Next.js 14 开始,使用新的选项 viewportgenerateViewport 来替换这些选项。所有其他元数据选项保持不变。

0 人点赞