找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2344

积分

0

好友

342

主题
发表于 2025-12-30 21:27:45 | 查看: 22| 回复: 0

Next.js 16 官方介绍图:全栈能力赋予前端
图1:Next.js 16 版本发布,强调将全栈能力带到前端。

next@15 发布并引入 React Server Components (RSC) 特性以来,我便被其深深吸引,并开始在项目中正式采用 Next.js。经过一年多的深度使用,我对它的强大之处有了更深刻的理解。

起初,我认为只有 SEO 优先的项目才需要考虑 Next.js。但现在,我的观念已经彻底转变,将其定位为 全场景首选框架。这种心态的巨大变化,源于对其核心机制——特别是部分水合——的深入理解。

next@16 发布后,伴随 turbopack 的日益成熟,开发环境的响应速度已经达到了不输 Vite 的程度,这进一步印证了我的判断。

为什么是全场景首选?

提出“全场景首选”的观点可能显得非常激进。这里我想强调的是,即便是常规的后台管理系统,使用 Next.js 也比传统的 Vite + React/Vue 方案具备更显著的优势。

在开发 usehook.cn 的过程中,我的项目经历了一次重大重构。最初版本我选择了 Vite + React,后来才重构为现在的 Next.js

重构的原因主要有两个。首先,用户在初始访问时,页面需要加载的包体积过大,导致首屏加载速度不稳定,部分用户反馈初始访问有时会非常慢。

为了解决这个问题,我尝试了多种方法,最主要的两点是:

  1. 将静态资源部署到 CDN 上。
  2. 通过代码分割实现页面的按需加载。

但折腾许久后,我发现效果有限。一方面,开发中已有意识地控制包体积,优化空间不大;另一方面,项目内置了许多渲染工具(如 Markdown 渲染、代码块渲染等),几乎是每个页面都必需的,尤其是代码块和数学公式渲染相关的包,体积相当庞大。

另一个问题是,过大的包体积上传至 CDN 后,流量消耗也很大,时常需要补充流量包。

于是,我萌生了基于 Next.js 重构整个项目的想法。尽管当时项目已非常庞大,重构成本很高。但我确信,Next.js 的特性能够从根本上解决包体积过大的问题

事实证明了这一点:重构前,首屏加载的 JS 包体积在 gzip 压缩后仍有 2MB 多;重构后,这一数字骤降至 100KB 左右,提升幅度极为夸张。

+ First Load JS shared by all            99.2 kB
  ├ chunks/215-319cb6c4fa92d97f.js       44.6 kB
  ├ chunks/4bd1b696-9a8bfc82401e0b67.js  52.6 kB
  └ other shared chunks (total)          1.95 kB

这就是 RSC + 部分水合 的威力。虽然整个项目的所有代码都是用 React 编写的,但 Next.js 可以在构建阶段,提前将非交互部分的渲染逻辑处理成静态 HTML。然后通过部分水合,在页面运行时,仅处理交互部分的逻辑。

这意味着,网页在运行时只需执行剩下的一小部分动态渲染逻辑,从而实现了极致的性能体验。

这里特指 App Router,而非 Pages Router。

Svelte 的 Signal 相比,这是一种不同思路的 细粒度更新。只要你的项目中存在静态渲染的部分,Next.js 就能展现出比 Svelte 更强大的优势。

什么是部分水合?

早年使用 JSP/PHP + jQuery 开发的项目,在支持 SEO 的同时,还能做到极致的性能体验。项目在服务端处理好 DOM 结构后,在客户端仅需通过 jQuery 获取对应 DOM 并实现交互逻辑即可。

让 DOM 具备交互逻辑的这个过程就可以理解为“水合”。

但这种模式有一个致命缺陷:开发体验不佳。因此,随着现代前端框架和工具链的发展,该模式逐渐被淘汰。然而,我们不得不承认,由于没有“水合”开销,这类项目在生产环境上的性能表现,远优于同构项目。

传统的同构项目需要进行全量水合,这导致 TTI(首次可交互时间) 指标表现较差。水合的目的与 jQuery 类似,都是为了赋予 DOM 交互能力。但由于整个应用完全使用 React/Vue 开发,我们不得不进行全量水合,重新动态渲染整个页面。

Next.js 的部分水合正是为了解决这个问题。如下代码所示,尽管整个项目都用 React 编写,但 Next.js 可以将静态部分在构建 (build) 时处理为静态 DOM 结构,只在页面运行时对剩余的动态部分进行水合。这是一种值得深入了解的前端工程化实践。

import { Suspense } from 'react'
import InteractiveChart from './InteractiveChart'
import StaticContent from './StaticContent'

export default function Page() {
  return (
    <div>
      {/* 完全静态,在 build 时渲染,无需水合 */}
      <StaticContent />
      <Suspense fallback={<Loading />}>
        {/* 只有这部分需要水合 */}
        <InteractiveChart />
      </Suspense>
    </div>
  )
}

这种细粒度控制使得 Next.js 能够在服务端渲染出完整的 HTML,然后在客户端仅对必要的组件进行“激活”,大大减轻了客户端的 JavaScript 负担。

Remix 中也提出了类似的概念:Remix Islands(岛屿架构)。Remix 认为,每一个需要交互的区域都是一个独立的“岛屿”,应用只需对这些“岛屿”部分进行水合。

与 Svelte 的对比

谈到性能,我们通常认为在客户端渲染方案中,Svelte 已做到了极致。它利用预编译,在构建时进行依赖收集和数据绑定,实现静态提升,并将状态变化转化为直接操作 DOM 的高效指令,从而绕过了虚拟 DOM。

Svelte 这种方式,在运行时的框架开销非常小

<!-- Svelte 的响应式是编译时确定的 -->
<script>
  let count = 0;

  function increment() {
    count += 1; // 编译为直接操作 DOM 的代码
  }
</script>

<button on:click={increment}>
  点击次数: {count}
</button>

因此,Svelte 非常适合开发注重动效的官网首页、活动页或商品介绍页等项目(例如最新的苹果官网就基于 Svelte 开发)。

Svelte 的逻辑是:既然虚拟 DOM 有开销,我就把更新做得足够细,实现精准的“点对点”更新。

Next.js 的逻辑则是:既然 JavaScript 的下载和执行是主要瓶颈,那我就干脆不向客户端发送多余的 JS。

在 Svelte 中,即使渲染高效,你仍需将所有处理交互的逻辑下载到浏览器。而 Next.js 结合 RSC 后,可以将大量静态内容提前处理好,只有真正需要交互的 孤岛(Islands) 才会被发送并进行 水合。这种方式不仅减少了 JS 包体积,也大幅减少了需要维护的虚拟 DOM 数量,从而显著降低了虚拟 DOM 本身的开销。

仅从 客户端开发 的角度,我做了一个对比图:

Next.js 16 SSG/CSR 与 传统CSR 性能特点对比
图2:Next.js SSG/CSR 与传统 CSR 在构建、性能、SEO等多方面的对比。

显然,在 Turbopack 的加持下,即使我们的项目完全没有静态渲染部分,也能获得接近 Vite 的开发体验。

当然,如果你的项目几乎没有静态内容,全部需要动态渲染(例如重交互的编辑器、在线 Excel),那么 Next.js 的优势就不那么明显了。

Turbopack 现状如何?

根据我的使用体验,Turbopack 在编译速度上确实非常快。即使项目庞大,也能获得不输 Vite 的开发体验。

我的项目 usehook.cn 拥有 700 多个页面,每次更新代码后的编译耗时大约在 300ms 多一点。

Next.js Turbopack 编译耗时截图,显示多次编译均在300ms左右
图3:项目使用 Turbopack 的编译耗时记录,多次编译稳定在 300ms 左右。

在第三方库的兼容性上,由于我的项目使用了较多小众的三方库,而它们在最近一年内都陆续获得了兼容。

因此,我可以得出结论:Turbopack 在兼容性方面的处理已经非常成熟。

Next.js 的其他优势

本文并未花大量篇幅介绍 Next.js 在服务端的表现,而是更多地将重心放在与传统 SPA 方案的对比上,因为大家可能对后者更熟悉。实际上,Next.js 在服务端渲染方面的表现更为优秀。

例如:

  1. 默认支持的 Link 组件预渲染(预取)。
  2. 能够更快获得交互响应的流式渲染(Streaming)。
  3. 对 SEO 友好。
  4. 完整且极简的文件路由系统。
  5. 强大且活跃的生态系统。
  6. 许多云部署平台(如国内较新的 EdgeOne Pages)都优先提供了对 Next.js 的特殊优化支持。
  7. 服务端的动静混合渲染模式(PPR, Partial Prerendering)。
  8. next@16 中更支持了 组件级别的细粒度增量更新

除此之外,Next.js 还可以作为 一个全栈框架纯服务端框架,来应对大多数中小型项目。它可以说是开发体验最好的全栈框架之一,提供了前后端一致的开发体验和数据类型。

总结

Next.js 的发展理念体现了一种 混合架构 思维。它正视浏览器的局限性,并利用 预渲染服务端算力 来弥补。这一年多的使用体验告诉我,Next.js 的强大在于它为开发者提供了一把精准的尺子,让你能够在性能与开发效率之间,找到那个完美的平衡点。

目前在国内,能够充分理解 Next.js 的 RSC 与部分水合之强大的人和团队还不多,主要在一些大型互联网公司中较受欢迎。但面向海外的团队,基本上都已拥抱了 Next.js

在我看来,RSC + 部分水合 是未来非常明确的发展趋势。即使在 Nuxt (Vue) 中,也开始引入 Server Components 的概念(尽管目前还是实验性功能)。

// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    componentIslands: true
  }
})

而在 next@16 中,经过两个大版本的迭代,关于 RSC + 部分水合 的构想已基本成熟并落地。对于希望深入探索现代 Web 开发前沿的开发者,可以在 云栈社区 找到更多相关的深度讨论和技术资源。




上一篇:深度对比C/C++、Java与Python程序的底层运行机制
下一篇:前后端分离架构详解:实现方式、优缺点与适用场景分析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-11 08:35 , Processed in 0.197205 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表