首页 / 文章

Next.js还是搭配Vite的纯React?根据项目需求选择合适的框架。

一种以需求为先的决策方法,用于判断新的React项目是需要Next.js还是搭配Vite的纯React,涉及SEO、SSR、托管、路由以及团队使用体验等方面。

发布者:REACTAPP.TOP阅读约 9 分钟2085 词

来源: When (Not) to Use Next.js: A Guide for React Developers

在许多 React 团队中,还没人提出问题,Next.js 就早已成为首选答案。它的文档非常出色,生态系统庞大,部署过程顺畅,而且人们普遍认为它能提升网站速度并帮助其更容易获得排名,因此用它来启动每个项目似乎都是最稳妥的选择。不过,框架终究只是具有特定功能的工具,Next.js 在不适合的项目中可能会带来诸多麻烦,而在适合的项目中则能节省不少精力。以下是一种实用的决策方法:明确 Next.js 能解决的实际问题(服务端渲染、SEO、混合渲染),它能在哪些方面真正发挥作用,哪些情况下使用 Vite 配合普通 React 更为合适,以及如何将这一选择作为需求而非个人偏好提交给团队。

Next.js 实际上为 React 带来了什么

抛开营销宣传不谈,Next.js 的核心作用在于决定 React 代码的渲染方式和位置。具体而言,它提供了:

  • 在 React 之上构建的服务器端渲染(SSR)、构建时静态生成(SSG)及其组合技术。
  • 基于文件的路由系统,通过文件夹结构来确定 URL,而非手动编写路由表。
  • 与前端一同提供的轻量级后端层:API 路由处理程序、中间件和边缘函数,使得单个代码库即可支撑完整的前后端应用。
  • 与现代托管平台深度集成,尤其是 Vercel,在缓存、边缘交付和部署方面表现优异。

以上内容可概括为一句值得在后续讨论中牢记的话:当项目的初始加载性能、SEO 以及将前端与后端需求整合到同一框架中真正重要时,Next.js 才能展现出其价值。以下每种场景其实都在验证这一观点。

Next.js 能显著提升效果的项目

搜索可见性及首次加载速度是业务需求

有些产品的成败取决于自然流量以及给用户的初次印象:

  • 营销网站和产品着陆页
  • 内容丰富的博客和文档平台
  • 依赖搜索功能的电商店铺

对于这类应用,服务器端渲染和静态生成并非可有可无的奢侈功能。在任何JavaScript代码执行之前,浏览器就已经收到了完整的HTML内容,这样用户就能更快看到内容,同时爬虫也能索引到实际文本而非空根元素。Next.js还允许你预先渲染包含数据的页面,按路由清晰地管理元标签,并通过增量静态生成技术,在内容发生变化时仅更新相关部分而无需重新构建整个网站。虽然也可以在纯单页应用中实现类似功能,但往往难以达到如此整洁的效果。

您希望有一个适用于整个技术栈的框架

可以考虑以下类型的项目:

  • 小型或中型的 SaaS 产品
  • 由少量已认证接口支持的仪表板
  • 前端和后端由同一团队开发的典型 Web 应用

Next.js 允许 API 代码与 React 组件共存于同一个项目中。您可以在 app/api 中编写接口处理程序(如果使用旧版的 Pages Router,则为 pages/api),利用中间件进行身份验证、本地化处理及重定向操作,最终将整个应用部署到任何支持 Next.js 的平台,包括但不限于 Vercel。

对于单个开发者或小型团队而言,这种整合非常有价值。无需搭建独立的 Node 或 Express 服务器,也不需要维护额外的部署流程。服务器逻辑与使用它的组件位于同一位置,框架则负责协调两者之间的路由与渲染工作。

公共区域和私有区域需要不同的渲染方式

许多应用程序自然而然地分为两大部分:一类是基本静态的公共页面,如首页、价格信息和文档;另一类则是动态的登录后区域,如控制面板或管理员控制台。Next.js 能很好地处理这种混合结构。你可以为那些很少变化的页面生成静态内容,在服务器端渲染针对不同用户的页面,而对于那些交互性很强的组件,则只在客户端渲染,因为服务器端渲染对其提升作用有限。真正的优势在于能够为每条路由选择合适的渲染策略,这样无需更换框架或维护两个代码库,就能针对产品的各个部分优化性能。

通常更适合使用纯 React 的项目

这类情况很常见,也正是团队出于习惯往往会选择 Next.js 的场景。

那些没人会通过搜索找到的客户端应用

想想内部操作界面或分析仪表板、需要登录才能进入的管理面板,以及用户直接通过应用访问而非通过搜索引擎进入的工具。在这些产品中,所有数据都是在应用加载后才获取的,初始的空白HTML文档并无意义,因为爬虫并非目标用户群体,而真正重要的性能问题都集中在客户端:状态管理、数据获取以及渲染效率。

Next.js 带来了许多你不会用到的服务器功能、不必要的服务器运行时,以及与路由和数据加载相关的额外概念。使用 Vite、Parcel 或甚至普通的 webpack 配置构建的 React 应用通常迭代速度更快,也更容易被大家理解。如果你想回顾这类配置的相关内容,可以查看我们关于首个 React 和 Vite 应用的操作指南。

一个有用的判断标准是:如果所有重要页面都需要身份验证,且用户只能通过已知 URL 或应用外壳才能访问,那么 Next.js 就是可选而非必需的。

小部件、组件库及可嵌入工具

有时交付物根本就不是网站。它可能是发布在 npm 上的可嵌入小部件、共享的设计系统,或是要嵌入到其他应用中的单页工具。你交付的是可复用的 UI,而非页面,因此路由、SSR、SSG以及固定的文件夹结构其实解决的是你根本不存在的问题。

出于三个原因,精简版的 React 构建方式是更好的选择。你可以直接按照框架规范进行构建和发布,无需绕开这些规则;你的包的使用者可以决定其渲染方式和位置;同时还能避免将仅适用于 Next.js 的假设硬编码进本应能在任何地方运行的代码中。如果你的项目根本没有真正的页面,以页面为中心组织的框架就不是合适的起点。

不与文件夹对应的路由

基于文件的路由方式对许多应用来说很方便,但它仍然存在局限性。URL结构与目录结构紧密绑定,某些复杂的路由模式需要借助变通方法,而过度依赖数据驱动的路由方式则可能显得生硬。如果你的应用拥有深度嵌套且高度动态的路由结构、不符合文件树结构的导航模型,或是受业务规则约束的特殊URL格式,那么将React与React Router这样的编程式路由库结合使用可能会更合适。在代码中定义路由能让你完全掌控路由逻辑,而无需让设计屈从于框架预期的布局。

需要思考的问题是:基于文件的路由方式是否能简化你的思维模型,还是只会带来更多困扰?如果它带来困扰,那么纯React可能才是更合适的选择。

主要为静态内容,交互性较低

Next.js 虽然能够生成静态网站,但其输出仍包含 React 运行时以及水合处理的开销。对于简单的营销页面、交互性有限的文档、作品集以及小型内容网站而言,这往往意味着需要传输远超实际需求的 JavaScript 代码。而像 Astro、Eleventy 或 Hugo 这样的静态网站工具,或是仅使用手工编写的 HTML、CSS 并在必要时添加少量 JavaScript 的方式,通常能产生更小的文件体积并简化部署流程。

简而言之,如果一个页面更像是文档而非应用程序,那么使用 React 元框架就相当于多了不必要的复杂结构。

无法运行服务器代码的托管服务

当你可以将应用部署到能够运行 Node 或无服务器函数的平台上,并且真正使用 SSR、边缘函数或 API 路由时,Next.js 才能发挥出最佳性能。但你的情况可能有所不同:比如使用仅支持静态内容的托管服务,如 GitHub Pages、处于纯静态模式的 Netlify,或是 CloudFront 后面的 S3;存在禁止长时间运行 Node 进程的政策;或是预算限制使得按每次无服务器调用付费不可接受。

在这种环境下,使用 Vite 等工具生成的静态 React 应用更为简单:生成资源后上传即可。Next.js 确实为这种情况提供了静态导出模式,但会放弃那些依赖服务器的功能,比如 ISR、中间件以及需要在请求时调用服务器的路由处理程序,因此请查阅最新文档以了解具体支持的功能。如果你使用 Next.js 却从未涉及 SSR、API 路由或中间件,那实际上你主要是在把它当作一个功能强大的打包工具来使用。

团队的经验也是决策因素之一

技术匹配度只是其中一半;团队的熟悉程度同样重要。假设该团队熟悉客户端 React 以及单页应用架构,但在 SSR、流式处理或服务器组件中的数据获取方面经验较少,且更注重交付产品功能而非投入平台建设。那么选择 Next.js 就意味着要面对:

  • 新的思维模式,包括服务器组件、服务器端数据加载以及路由规范
  • 与部署目标、缓存层及边缘节点行为相关的操作复杂性
  • 在渲染或水合过程出现故障时需要检查的更多环节

这样的投资绝对物有所值,但它确实是一笔成本。对于小型产品或内部工具而言,选择团队十分熟悉的技术栈往往比为了追求更现代的感觉而采用新技术更为明智。如果您正在权衡该框架的新功能,我们的现代 Next.js 功能对照表及各自替代的功能能帮助您了解还需要学习多少新内容。

新项目的决策清单

在启动任何以 React 为主的项目时,请先思考以下问题:

  1. 出于 SEO 或首屏加载性能的考虑,您需要 SSR 还是 SSG?如果需要,Next.js 是绝佳选择;如果不需要,普通的 React 就已经足够。
  2. 这是一个由真实页面构成的网站,还是主要以应用壳层形式存在?许多内容页面指向 Next.js;而单壳界面则表明是 React 单页应用。
  3. 你是否需要一个与前端并列运行的小型后端?如果同一代码库中包含 API 路由和中间件能满足你的需求,那么 Next.js 非常合适。如果已有专门的后端存在,无论是 NestJS、Spring Boot、Laravel 还是其他框架,使用 Next.js 的附加价值就会降低。
  4. 它将部署在何处,预算又是多少?如果有能力且愿意为服务器进程或函数调用付费,那么 Next.js 仍是一个可行选择。如果只能使用静态托管,那么轻量级的 React 构建通常更为合适。
  5. 团队目前擅长什么技术?如果大家都精通 React,但只有少数人了解 SSR 和服务器组件,那么需要考虑项目需求是否真的值得投入学习成本。

这一切都不要求你必须采取非此即彼的态度。你不必在所有项目中都使用 Next.js,也不必完全排除它。正确的做法是将其视为 React 工具箱中的一个选项,只有当它的优势符合你的需求时才刻意选用。

为团队明确选择方向

如果你是做出或影响这一决策的人,避免将其表述为“Next.js 太过复杂”,因为这听起来像是个人偏好问题。相反,应基于团队能够评估的权衡因素来说明:

  • “这个内部仪表板几乎无法从 SSR 或 SEO 中获益,因此使用 Next.js 只会增加开销而没有明显好处。”
  • “该组件库没有页面或路由功能,因此普通的 React 构建环境更为合适。”
  • “我们的托管服务仅支持静态文件,所以 Next.js 的许多优势都将无法得到利用。”
  • “在那些对性能和搜索功能要求较高的公开内容型产品中,我们会选择 Next.js,而内部工具则继续使用纯 React。”

这样的表述能让讨论聚焦于实际需求而非行业趋势,一旦需求发生变化,也便于重新审视决策。

让需求决定框架选择

选择 Next.js 还是纯 React 并非取决于哪个更现代,而是取决于你的项目面临的具体问题。在需要时,服务器端渲染、SEO、按路由渲染策略以及与后端同部署等功能能带来显著优势,而在不需要时则只会增加额外开销。请从上述清单中的需求出发,结合托管限制和团队的经验,让框架选择基于这些答案产生,而非相反。

相关阅读

  • URL状态、服务器状态与BFF:专为内部React应用设计的Vite技术栈:为何经过身份验证的内部React平台使用Vite、TanStack Router、TanStack Query以及独立的BFF能获得更好支持,以及何时这种情况不再成立。