Next.js Canary支持部分预渲染以实现更快的网站

目前,开发者必须在速度和功能之间进行选择。Next.js 中的一个实验性功能部分预渲染可能会改变这种情况。

译自 Next.js Canary Supports Partial Pre-Rendering for Faster Sites,作者 Loraine Lawson。

部分预渲染说起来很有趣,但编码起来却一点也不有趣——至少对于 Next.js 团队来说,最初是这样。

“当我们宣布并开始自己使用它时,它极其复杂,”

框架工程副总裁 Tom Occhino 告诉 The New Stack。“你可以让它工作,但让它启动并运行起来非常困难。”

他补充说,它需要高级配置,而且很容易出错。而且,如果这并不能真正说明问题,那么部分预渲染过程很难记录和解释。

“当我们自己使用它时,我们知道我们需要一个更简单的模型,于是开始了 [我们] 踏上今天

Next.js 15 之旅,”他说。“在 v15 中,我们极大地简化了开发人员 API 和与能够利用这些东西相关的开发人员体验。”

他补充说,它也更容易学习、理解和解释。

Occhino 说:“对于你的页面,你确实可以同时获得快速、静态、初始渲染和流式动态内容的优势。它在很多方面都很棒。”

Next.js 15 的实验性部分预渲染 功能在旧金山举行的 10 月份 Next.js 大会上备受瞩目。Next.js 属于前端云平台 Vercel 所有。

部分预渲染:要点

Vercel 软件工程师 Wyatt Johnson 已经从事部分预渲染工作两年了。在一次会议期间,他向听众解释了部分预渲染——他将其缩写为 PPR——以及 Next.js 如何实现它。

Johnson 说:“PPR 是一种渲染策略,它结合了静态渲染和动态渲染的优势。”“它允许你预渲染页面中静态的部分,同时动态获取和渲染其他部分。”

显示使用 Suspense 进行部分预渲染的代码。

显示使用 Suspense 进行部分预渲染的代码。照片由 Loraine Lawson 提供

他补充说,这给前端开发人员带来的好处之一是,它可以通过减少初始加载时间并为搜索引擎提供预渲染内容来提高性能和 SEO。Johnson 详细介绍了部分预渲染如何影响核心网络指标,特别是最大内容绘制,它衡量网站显示其最大内容元素需要多长时间。

他解释说,部分预渲染经过独特设计,旨在解决开发人员在优化此指标时遇到的部分问题。

他说:“它也从请求开始时进行衡量,但当屏幕上渲染出最大的可见元素时,它就完成了。”“这包括卸载当前文档、建立连接、执行重定向以及当然首次字节时间。”

他说,一个“好的”LCP 得分小于 2.5 秒,但这仍然是一段很长的时间,并补充说,更好的目标应在几百毫秒的范围内。

传统渲染的挑战

在 Web 开发中,通常有两种不同的渲染策略。

他说,静态渲染速度快,但缺少请求数据。它可以从边缘渲染整个页面,因此可以尽可能快地直接将其发送给用户。但他补充说,它缺乏读取请求数据的能力,而必须使用客户端请求来检索信息,从而导致到原点的昂贵往返。

他说,在 Next.js 中,当你想访问请求数据时,你可以调用请求数据 API,例如 cookie 或标头。这些仅在服务器组件中可用,一旦调用,整个页面就会被标记为动态,并选择退出静态渲染。

动态渲染包括请求数据,但由于服务器响应时间,它可能会很慢。动态渲染允许访问请求数据,并且 HTML 可以 在服务器端渲染。但这意味着用户必须等待,因为网络必须一直到达原点才能渲染 HTML 的第一个字节。

Canary 中提供的部分预渲染

Johnson 说,开发人员通常必须在速度和功能之间进行选择。部分预渲染旨在解决这一挑战。部分预渲染能够在构建时生成静态外壳。

一个 IDE 显示一个生态商店,旁边是 React 代码,突出显示了 Suspense 的使用。

一个生态商店应用程序展示了 Suspense 如何支持部分预渲染。照片由 Loraine Lawson 提供

“这直接从边缘提供给浏览器,同时向原点发送请求以完成动态渲染,然后在同一响应中流式传输,”他说。“它实际上由这两部分组成:包含外壳的静态流 [和] 包含所有动态数据的动态流。”

他表示,尽早向用户提供静态外壳非常重要,因为它允许 JS、CSS 和字体等资源尽早开始预加载。

Next.js 通过使用 React 来实现这一点,特别是在构建期间使用一个“小巧的预渲染函数”,他们称之为预渲染。它生成两部分:第一部分称为前奏或静态外壳。第二部分是延期状态,它使用 JSON 来描述静态外壳中包含的内容。

“当我们运行预渲染时,实际上发生的是我们正在输出一个由 HTML 组成的静态外壳,”他说。“我们正在输出此延期状态,它告知 React 静态外壳中包含哪些部分,以便它们可以恢复渲染。”

然后调用 Resume API,它创建一个流,编码器可以将其附加到静态外壳的末尾,该流同时被流式传输出去。他说,这一点的时机至关重要,因为“在向用户提供静态外壳的同时,我们也在原点启动动态调用,节省了宝贵的毫秒。”

“得益于部分预渲染的混合渲染方法,我们能够尽可能快地从边缘向用户提供静态外壳,从而最大程度地减少首次字节时间和首次内容绘制。” ——Vercel 软件工程师 Wyatt Johnson

这意味着,当浏览器已经通过链接头或标签从静态外壳中获取提示的静态资源时,代码已经在原点调用服务器来渲染该页面的动态部分,他继续说道。

“得益于 React 流,这些部分被交换为其悬念后备,这意味着我们甚至不必等待水化即可让页面加载所有这些部分,”他说。“与传统渲染方法的不同之处在于,在部分预渲染中,当它检测到正在访问请求数据时,它实际上并没有完全退出静态渲染。相反,它只是触发后备到最近的 Suspense 边界。”

该团队过去一年一直在努力解决的问题是如何检测到您尝试访问请求数据。在他的演讲中, Johnson 深入探讨了 他们如何实现这一点;但简而言之,它利用了 Promise、Node.js 事件循环和 React 服务器组件。

“Suspense 是我们的粘合剂,允许 [我们] 为页面动态部分的流式传输创建稳定的边界,”他说。“得益于部分预渲染的混合渲染方法,我们能够尽可能快地从边缘向用户提供静态外壳,从而最大程度地减少首次字节时间和首次内容绘制。”

Next.js 用户可以通过向其 Next.js 配置添加实验性 PPR 标志来尝试部分预渲染。这使页面能够使用新的渲染管道进行渲染。

他强调说,这现在是实验性的,并且没有计划为 Next.js 15 更改它。它确实需要安装金丝雀版本才能使用它。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注