Next.js 完全指南 — 第 1 章:Next.js 的出现、背景与核心理念(Part 1)

深入理解 Next.js 的历史背景、现代 Web 的核心复杂性、React 的缺陷、Next.js 的使命、App Router 的出现与意义。本章节为 2 万字内容的第一部分。

本章目标

  • 理解现代 Web 为什么越来越复杂
  • 理解 React 为什么需要一个框架
  • 理解 Next.js 出现的根本原因
  • 掌握 Next.js 架构背后的思想
  • 认识 App Router 作为未来标准的原因

1.1 为什么需要 Next.js?——现代 Web 的复杂性远超想象

如果你长期写 React,你一定对以下问题很熟悉:

  • 页面首次加载很慢
  • SEO 很差,Google 很难抓 JS 渲染的内容
  • Redux / SWR 越写越复杂
  • Webpack 版本升级变成痛苦噩梦
  • SSR 要自己搭 Node 服务
  • 前后端要维护两个仓库
  • 新成员入职成本巨大
  • 切换路由时白屏、闪烁
  • 性能指标(LCP/TTFB/FCP)屡屡不达标

这些问题并不是 React 的错,而是:

React 本质是 UI 库,不是框架。
它不负责渲染、路由、缓存、服务器逻辑、SEO、数据加载、部署……

因此每个 React 项目都需要手动组合一大堆工具:

React + react-router + Redux + SWR + Webpack + Express + SEO 工具...

组合方式无限多,维护成本极高。

1.1.1 React 的“库”定位决定它无法解决全链路问题

React 团队的核心哲学是:

“UI = f(state)。其余不是 React 的责任。”

React 不关心:

  • API 如何写
  • SEO 如何优化
  • Bundle 如何拆分
  • SSR/SSG/CSR 如何协调
  • 表单如何提交
  • Cookie 如何管理
  • 数据库如何读写

最终导致 React 项目不可避免地出现:

  • 结构膨胀
  • 工具碎片化
  • 性能难以优化
  • 团队协作困难

现代 Web 正需要一个“统一全栈能力”的框架,这就是 Next.js。

1.1.2 现代 Web 应用已成为“操作系统级复杂体”

一个现代的 Web 应用(如 Twitter/Notion)需要:

  • 即时渲染
  • 即时更新
  • 缓存层
  • 边缘加速
  • 服务端渲染
  • 高度交互 UI
  • SEO
  • 图片优化
  • 字体优化
  • 国际化
  • 多租户支持
  • 用户系统
  • API 与数据库
  • 安全(CSRF/XSS/CORS)
  • 灰度发布
  • 服务编排

这完全不是“写网页”了,而是:

分布式全栈系统工程。

仅靠 React 绝对不够。

1.1.3 Next.js:React 的“现代全栈操作系统”

Next.js 的使命就是解决 React 无法解决的层面。

Next.js 内置提供:

  • 文件系统路由
  • SSR/SSG/ISR 混合渲染
  • App Router + Server Components
  • Route Handlers(内置 API 服务)
  • Server Actions(更现代的后端函数)
  • 全自动代码拆分
  • 图片优化、字体优化
  • 自动缓存与 revalidate
  • 边缘运行(Edge Runtime)
  • 一键部署(Vercel 集成)

它让开发者回归:

只写业务,而不是打仗。

1.1.4 为什么 Next.js 不是“另一个 React 框架”,而是行业默认?

原因如下:

阶段技术趋势Next.js 的意义
2015 SPA 浪潮React 主宰 UIReact 组件化时代开始
2018 SSR 回归SEO 需求增长Next.js 成 SSR 标准方案
2020 Jamstack静态化 + CDNNext.js 引入 SSG + ISR
2022 React 18并发特性 + RSCNext.js 实现 App Router
2023-2025 全栈统一统一前后端Next.js 成为新默认

甚至 React 官方文档明确推荐:

新项目优先选择 Next.js。

Next.js 已成为:

  • 最主流的 React 框架
  • 最适合构建 SaaS/B2B/内容系统的框架
  • 最适合团队协作的工程体系
  • 最平衡性能、可维护性和 DX 的方案

1.2 React 本身的结构性缺陷:为什么它需要一个框架?

React 本身存在几个根层问题。

1.2.1 React 无法解决首屏性能问题(白屏)

SPA 页面加载流程:

  1. 下载 HTML
  2. 下载 JS
  3. 执行 JS
  4. React 渲染 UI
  5. 请求数据
  6. 渲染内容

期间可能经历:

3–5 秒白屏。

Next.js 用 SSR 改变这一切:

  • 服务端直接返回渲染好的 HTML
  • 用户瞬间看到页面
  • 后续再请求数据变为可交互

1.2.2 React 不负责 SEO

SPA 的 HTML 是空壳:

<div id="root"></div>
<script src="main.js"></script>

Google 需要执行 JS 才能看到内容:

  • 成本高
  • 可能失败
  • 低网速区域完全加载不了

Next.js 提供:

  • SSR(Server-Side Rendering)
  • SSG(Static Site Generation)
  • ISR(Incremental Static Regeneration)
  • Metadata API(用于动态 SEO)

彻底解决 SEO 问题。

1.2.3 React 不负责渲染策略选择

你必须自己回答:

  • 是否 SSR?
  • 是否静态生成?
  • 内容多久更新?
  • 是否缓存?

在 Next.js 中:

每个页面可以独立选择最优渲染方式。
可以随时切换,无痛迁移。

1.2.4 React 缺少“工程级”的支柱体系

React 没有:

  • 路由
  • API 服务
  • 数据层
  • 文件组织规范
  • 服务端渲染能力
  • 构建系统
  • 性能优化默认值
  • 部署链路

Next.js 提供的正是这些基础设施。

1.3 Next.js 的目标:重构 Web 开发方式

Next.js 有三个核心使命。

1.3.1 使命一:让 React 成为“真正的应用框架”

Next.js 补足 React 缺失的部分,包括:

  • 路由
  • 缓存
  • SSR/SSG/ISR
  • API 层
  • 文件规范
  • 项目结构
  • 性能优化
  • 部署集成
  • 数据访问(RSC)

React 负责 UI,而 Next.js 负责工程。

1.3.2 使命二:让 Web 开发回到“简单模式”

现代 Web 开发工具太多:

  • Webpack
  • Babel
  • Redux
  • React Router
  • Express
  • SWR
  • GraphQL
  • CI/CD

Next.js 的哲学:

零配置(Zero Config)。

只需:

npx create-next-app

你就获得完整体系。

1.3.3 使命三:统一前后端(Fullstack)

App Router + Server Components = 前后端自然融合。

  • UI 在组件
  • 数据获取在组件
  • 数据库访问在组件
  • API 在组件
  • 缓存在组件
  • 权限在中间件
  • CDN 缓存在框架自动处理

你再也不用维护:

  • backend(Node.js)
  • frontend(React)
  • API(Express)

Next.js 就是全部。

1.4 Web 的四个时代:为什么必须进入 App Router 时代?

理解历史才能理解趋势。

1.4.1 时代 1:传统页面时代(2000–2010)

代表技术:

  • PHP
  • JSP
  • ASP

特征:

  • 服务端模板渲染
  • 页面刷新
  • SEO 强
  • 性能好

缺点:

  • 无法构建复杂前端交互
  • UI 组件化很弱

1.4.2 时代 2:SPA 时代(2010–2018)

代表技术:

  • React / Vue / Angular
  • webpack
  • csr-only 架构

优势:

  • 组件化
  • 单页面应用体验

缺点:

  • 首屏慢
  • SEO 差
  • JS 包巨大
  • 工程化复杂

1.4.3 时代 3:SSR + 静态化时代(2018–2022)

代表技术:

  • Next.js(pages 路由)
  • Gatsby
  • Nuxt

解决的问题:

  • SEO
  • 首屏性能
  • 静态部署
  • CDN 加速

但仍存在:

  • SSR 负载高
  • Hydration 性能差
  • 大量 JS 必须下载

1.4.4 时代 4:RSC + App Router 时代(2023–2025)

React Server Components(RSC)首次提出终极目标:

把不需要在浏览器运行的代码,从客户端彻底移除。

App Router 是对 RSC 最完整的框架实现:

  • 服务器渲染 UI
  • 不发送不必要的 JS
  • 能直接访问数据库
  • 能自动缓存
  • 默认可 Streaming
  • Page/Route/API/Action 统一

这是现代 Web 体系最重要的架构升级。

1.5 为什么 App Router 是未来十年的主流?

核心原因:

1. JS 体积下降 70%–90%

因为大部分 UI 不需要在客户端执行。

2. SEO 天然优秀

页面渲染在服务器。

3. 性能显著提升

Streaming + 数据层在服务端执行。

4. 代码结构更简单

组件就是页面、就是 API、就是数据层。

5. 团队研发效率提升

统一模型、统一生命周期、统一结构。

1.6 小结:理解 Next.js 的价值

Next.js 的出现不是偶然,而是:

  • Web 越来越复杂
  • React 只负责 UI
  • Web 性能瓶颈越来越明显
  • 前后端割裂越来越痛苦
  • 团队协作成本越来越高

最终 Next.js 成为:

现代 Web 的新基础设施。

1.7 Next.js 架构的演进:从 pages/ 到 app/ 的时代转折

Next.js 的最大变化发生在版本 13。

从 2016 年到 2022 年,Next.js 的核心结构围绕:

pages/
index.tsx
about.tsx
blog/[slug].tsx
api/users.ts

这是一个以 文件系统 routing(文件即路由) 为核心的结构,使 Next.js 在当时成为 React 生态中最易用的框架。

然而,随着 React 18 发布、Server Components 技术成熟,Next.js 官方意识到:

Pages Router 的架构已经无法充分发挥 React 18 的能力。

于是 App Router 诞生。

它不是简单的目录替换,而是:

  • 完全新的路由心智模型
  • 新的数据获取方式
  • 新的渲染生命周期
  • 新的服务端运行模式
  • 新的缓存策略
  • 新的 React 代码执行方式

它标志着 Next.js 进入了 Server Components 主导的时代

1.7.1 Pages Router 的优缺点分析

Pages Router 是历史遗留但仍有价值的模式。

Pages Router 的优点

  • 心智简单:一个文件等于一个页面
  • SSR/SSG/ISR 配置直观(getServerSideProps 等)
  • 生态成熟,资料大量
  • 许多老项目仍基于它

Pages Router 的结构限制

  1. 数据获取方式过多、过杂

Next.js 12 时,数据获取方式包括:

  • getServerSideProps
  • getStaticProps
  • getStaticPaths
  • getInitialProps
  • getServerSidePaths
  • API Routes
  • SWR / React Query

初学者面对七八种方法会困惑不已。

  1. 逻辑分散

页面的 UI 在组件中,数据在外面:

export async function getServerSideProps(ctx) {
  const data = await fetch(...);
  return { props: { data } };
}

export default function Page({ data }) {
  return <List data={data} />;
}

存在的缺点:

  • UI 和 Data Pipeline 分离
  • 难以组合异步逻辑
  • 组件内部无法直接访问数据库
  • 难以分片渲染(Streaming 不自然)
  1. Hydration 有较大性能负担

因为:

  • SSR 输出 HTML
  • 仍需要把整个页面的 JS 下载并执行
  • 状态必须从服务器同步到客户端
  • 组件树越大,耗时越长

大型页面会在 hydration 阶段卡住用户界面。

  1. 组件粒度固定:全部属于客户端组件

Pages Router 的组件本质上都是 “client-bound”:

  • 必须在客户端执行
  • 必须在浏览器可用
  • 必须具备 hydration

这导致:

  • JS bundle 很大
  • 服务器工作量偏小,但浏览器压力极高
  • 数据库访问必须通过 API,再通过 fetch 层层转发

大量不需要在浏览器执行的工作被迫跑在客户端,浪费性能。

1.7.2 App Router 的出现是一场革命

App Router 本质上是一次:

“用新架构重写 Next.js 的灵魂。”

它引入的最大区别是:

  • 默认使用 React Server Components (RSC)
  • 页面 = 服务器组件
  • 不需要 hydration 的部分不会被打包到客户端
  • 能直接访问数据库
  • 数据获取自然从组件内部进行
  • 自动缓存
  • 自动 Streaming
  • API 可用 Route Handler 或 Server Action
  • 布局(Layout)成为一等公民

这与 Pages Router 最大的差别是:

从“前端驱动” → 转向“服务器驱动”。

它改变了 20 年来 Web 的思维方式。

1.8 App Router 的基本结构与心智模型

App Router 的核心思想非常一致:

目录结构就是应用结构。

典型结构:

app/
  layout.tsx
  page.tsx
  dashboard/
    layout.tsx
    page.tsx
    analytics/
      page.tsx
  api/
    users/
      route.ts

在 App Router 中:

  • layout.tsx:服务器组件,用于包裹子路由
  • page.tsx:特定路由的页面逻辑
  • loading.tsx:该路由的加载状态
  • error.tsx:该路由的错误边界
  • route.ts:HTTP 请求处理器(API)
  • not-found.tsx:404 页面

页面渲染过程完全由服务器控制。

1.8.1 服务器组件:页面的默认模式

App Router 的最大特点:

没有 "use server" 也没有 "use client" 的文件 = Server Component

Server Component 的意义:

  1. 在服务器执行,不进入打包
  2. 可以直接读数据库
  3. 可以直接访问文件系统、环境变量
  4. 不需要 hydration
  5. 不增加 bundle 体积
  6. 天然支持 Streaming
  7. 自动缓存

这使得:

  • 数据获取更快
  • 页面更快
  • 服务器压力更可控
  • 更节能
  • 更 SEO 友好

1.8.2 客户端组件(use client)

只有需要浏览器能力的组件才需要:

"use client";

例如:

  • 动画
  • 按钮点击事件
  • 表单本地状态
  • 图表、拖拽、编辑器组件
  • 浏览器 API(localStorage、window)

最佳实践是:

把绝大多数组件保持为 Server Component,只在最必要时切入 Client Component。

这样可使整个页面打包体积大幅减小。

1.9 Next.js 的核心理念(Design Principles)

Next.js 的设计哲学贯穿所有架构决策。理解这些原则非常重要,它们影响整个 App Router 的心智模型。

哲学 1:文件即路由(File-system Routing)

路由和 URL 的关系变得清晰自然:

app/blog/[slug]/page.tsx  →  /blog/:slug

不需要:

  • React Router
  • Route table
  • 复杂匹配规则

只需要:

  • 将文件放在你认为它应该在的位置

哲学 2:默认服务器渲染(Server-first)

不同于老年代 SPA(Client-first):

  • 页面不再默认跑在客户端
  • 页面逻辑不再默认运行在浏览器
  • 服务端先执行,再按需给予客户端能力

表现为:

  • 页面组件是服务器组件
  • 布局是服务器组件
  • 数据获取天然在服务器执行
  • 缓存天然在服务器出现

哲学 3:客户端能力显式声明(use client)

客户端能力不再隐式污染任何组件:

旧时代(React SPA):

  • 每个组件自动变成浏览器 JS
  • 组件越多,bundle 越大

新模式:

  • 组件默认不进客户端
  • 必须明确加 "use client" 才会进入客户端

这减少了惊人的 JS 开销。

哲学 4:渲染与数据获取天然结合

旧模式:

  • UI 代码在组件
  • 数据在 getServerSideProps 或 API Route
  • 两边分裂
  • 组件内部不能使用 await

新模式:

export default async function Page() {
  const posts = await db.post.findMany();
  return <PostList posts={posts} />;
}

数据获取直观自然:

  • 无需跳转 API 层
  • 无需在客户端 fetch 再 setState
  • 不存在 SWR/React Query 的额外复杂性

开发体验明显提升。

哲学 5:Streaming 默认可用

页面成为 流式页面

你可以做到:

await slowFunction(); // 先发送布局
return <Content />;   // 再更新内容

甚至可以让:

  • 页面顶部先渲染
  • 底部慢数据几秒钟后再渲染

带来类似 App 的即时体验。

哲学 6:全栈统一(Fullstack Integration)

App Router 让你可以在一个项目中:

  • 页面组件
  • API 路由
  • 数据库访问
  • 服务器逻辑
  • 鉴权
  • 静态资源
  • 国际化
  • 边缘逻辑

全部统一在一个目录:

app/

这是巨大的心智简化。

1.10 为什么 Next.js 成为 React 官方推荐框架?

React 官方文档(2023-2025)推荐:

New React projects should use Next.js.

原因包括:

  1. 最完整实现 React 18 特性(RSC)
  2. 最丰富的生产级能力(SSR/SSG/ISR/Streaming)
  3. 最优的生态系统支持(Vercel + CDN + Edge)
  4. 最符合工业生产需求(SaaS、B2B、内容平台)
  5. 最佳的 DX(Developer Experience)
  6. React 官方与 Vercel 密切合作开发 RSC

可以说:

Next.js = React 的工程化延伸。

1.11 Next.js 的生态价值:它不只是框架,还是完整平台

Next.js 的生态包括:

  • Turbopack(Rust 写的打包器)
  • Next.js Image Optimization
  • App Router API
  • Route Handlers
  • Server Actions
  • Vercel Edge Network
  • Vercel Analytics
  • Vercel Observability
  • next/font 自动子集化
  • next/image 自动裁剪、webp 转码
  • next/script 优化脚本加载

这意味着:

Next.js 是现代 Web 的“底层运行时 + 构建系统 + 部署平台”。

不仅仅是一个开发框架这么简单。

1.12 为什么现代 Web 越来越偏向“服务端优先”(Server-first)?

近几年,Web 开发出现了一个明显趋势:

从“客户端优先”(Client-first)
→ 回到“服务器优先”(Server-first)

为什么会发生这种趋势逆转?

1.12.1 原因一:浏览器负担过重,客户端组件正在成为性能瓶颈

经典 SPA 模式需要:

  • 下载整个 JS bundle(动辄 500KB~2MB)
  • 执行 JS(昂贵)
  • Hydration(极昂贵)
  • 前端调用后端 API
  • 缓存管理
  • 状态管理
  • 大量代码在客户端执行

浏览器本身的性能瓶颈包括:

JS 执行限制

浏览器需要:

  • 解析 JS
  • 编译 JS
  • 执行 JS
  • 执行 React hydration
  • 应付大量 DOM 更新

尤其在低端设备上,会出现:

  • 卡顿
  • 滚动不顺畅
  • 路由切换掉帧
  • 交互延迟明显(LAG)

1.12.2 原因二:SEO、社交媒体预览、爬虫越来越重要

营销站、内容站、知识型网站对 SEO 非常敏感,需要:

  • 服务器输出 HTML
  • OpenGraph 元数据
  • 可预渲染的内容
  • Schema.org 信息

纯客户端渲染是无法满足的。

1.12.3 原因三:移动端用户剧增,网络质量参差不齐

全球范围来看,50%+ 用户来自移动端。

  • 网速慢
  • JS 执行能力弱
  • 内存小
  • CPU 不稳定

客户端渲染越多,性能越差。

1.12.4 原因四:Web 变成分布式系统,服务器更靠近用户(Edge)

有了:

  • Cloudflare Workers
  • Vercel Edge
  • Netlify Edge
  • Deno Deploy
  • Fastly Compute@Edge

服务器已经不再是“慢”的代名词,而是:

离用户只有几毫秒。

因此,在服务器执行逻辑 → 然后流式传递给用户,会比浏览器快得多。

1.12.5 原因五:数据层本来就应该在服务器

把数据从服务器 → 客户端 → 再 fetch → 再 setState → 再渲染

这是一条非常绕的链路。

典型的数据流:


DB → Backend API → Client fetch → React useEffect → State → UI

App Router 中,数据流变成:


DB → Server Component → HTML → Browser

链路缩短为原来的 1/3。

1.13 React Server Components(RSC):现代 Web 最革命的技术

要理解 App Router 的伟大,就必须理解 RSC。

RSC 的核心目标:

删除那些不需要在浏览器运行的代码。

这句话的含义极其深刻。

1.13.1 RSC 的黄金法则:组件默认在服务器执行

所有普通组件都是:

  • 在服务器执行
  • 不打包到浏览器
  • 不参与 hydration
  • 不需要 useState(除非你指定)

这意味着:

  • 浏览器执行更少
  • JS bundle 更小
  • 页面更快
  • 不再需要大量 API fetch
  • 可以直接在组件中访问数据库
  • 数据直达 UI,无需网络跳转

1.13.2 RSC 的传输格式:不是 HTML,也不是 JSON,而是专门的 RSC Payload

RSC 将 UI 编译成一种特殊格式(Wire Format):

例如:

$RSC_PAYLOAD = [
"$$typeof": "react.server.reference",
...
]

浏览器收到的是:

  • 原始 HTML(通过 Streaming 输出)
  • RSC 编译格式(用于更新节点)

这是 React 18 的底层渲染引擎的大升级。

1.13.3 RSC 带来的实际性能收益

✔ JS bundle 大幅下降(50%~90%)

因为服务器组件无需打包。

✔ Hydration 范围减少

只对客户端组件区域进行 hydration。

✔ 无需 SWR / React Query

数据获取直接放到组件内部。

✔ 无需 Context 传递异步数据

组件内部直接 await。

✔ 页面跳转更快

App Router 采用新的刷新机制(partial rendering + streaming)。

✔ 更容易缓存

RSC 深度集成 Next.js Cache Layer。

1.14 为什么传统 React SSR 已经过时?

传统 SSR 模式存在三大问题:

1.14.1 Hydration 成本会随着页面复杂度指数级增加

SSR 的流程:

  1. 服务器渲染 HTML
  2. 浏览器下载 JS
  3. 浏览器执行 JS
  4. React 对整个页面进行 hydration

Hydration 是:

  • CPU 密集型
  • 有同步阻塞
  • 忽略超大 DOM 的优化可能性

页面越复杂,hydration 时间越长。

1.14.2 SSR 引入了“双重渲染问题”(服务器一次 + 客户端一次)

SSR 需要:

  • 服务端执行组件
  • 客户端再次执行组件

这导致:

  • 代码运行两次
  • 性能浪费
  • 开发者处理两个环境(server + client)
  • 缓存容易出错
  • 数据流混乱

1.14.3 SSR 无法避免“全部 JS”下载到客户端

即使你只用到了部分功能,React 也会打包整棵组件树。

这是 SPA 的根源性问题。

1.14.4 RSC 才是终极解决方案

RSC 解法:

  • 服务器组件不进入客户端
  • 不参与 hydration
  • 直接输出 HTML + RSC payload
  • 客户端组件小范围 hydration

这是对 SSR 架构的颠覆式重写,而不是优化。

1.15 Next.js 的 Server-first 架构 vs 传统前端框架

下面从结构性对比来说明 Next.js 的优势。

1.15.1 与 Vue / Nuxt 的对比

框架渲染模型数据获取服务端执行全栈能力
VueCSR手动
Nuxt 2SSR/CSRAPI 分离有限
Nuxt 3部分类似 RSC强化中强
Next.js App RouterRSC + SSR + Streaming组件内 await极强

Nuxt 3 走向了“服务端优先”,但 RSC 是 React 独有的优势,Nuxt 只能模仿,不可能拥有相同实力。

1.15.2 与 Remix 的对比

Remix 的理念是“服务器优先”,但:

  • 只有 SSR
  • 没有 RSC
  • 大量 hydration
  • JS 发送到客户端
  • 性能不如 Next.js

Remix 更适合轻量应用,不适合大型 SaaS 或 B2B。

1.15.3 与 Vite + React 的对比

Vite:

  • 快速开发服务器
  • 零 SSR 能力
  • 没有服务器组件
  • 没有全栈能力

适合:

  • 小型前端项目
  • 原型
  • 对 SEO 不敏感的 H5 页

不适合:

  • B2B
  • SaaS
  • 营销页
  • 复杂系统

1.16 Next.js 在 SaaS / B2B / 管理后台中的独特价值

现代 SaaS 产品需要:

  • 多租户
  • 登录鉴权
  • 数据库读写
  • 性能优化
  • 全链路缓存
  • 实时能力
  • 后台管理界面
  • 国际化
  • API
  • 文件上传
  • Edge Logic

Next.js 提供:

  • Server Components → 页面即服务器逻辑
  • Route Handlers → 内置 API
  • Server Actions → 后端函数
  • 中间件 → 权限、租户、重定向
  • 缓存层 → ISR / revalidate
  • app/ 目录结构 → 分层清晰
  • 内置 SEO
  • 组件级 Streaming
  • Vercel 部署 → 全球加速

这些能力组合起来,使 Next.js 成为:

2025 年 SaaS 产品的最优解。

尤其适合:

  • CRM
  • Dashboard
  • 工具站
  • 商家后台
  • 内容管理系统
  • 企业 B2B 平台
  • SaaS 控制台
  • 组织协作平台(Notion 类)

1.17 Next.js 的开发体验(DX)成为行业标杆

为什么工程团队喜欢 Next.js?

1.17.1 项目结构统一

所有项目结构一致:

app/
page.tsx
layout.tsx
api/
dashboard/

无需团队内部制定复杂规范。

1.17.2 数据获取统一

你不需要:

  • axios
  • useEffect
  • SWR
  • Redux
  • React Query

你只需要:

const data = await fetch(...)

或:

const data = await db.user.findMany()

1.17.3 全栈统一

无需 Express:

// app/api/users/route.ts
export async function GET() {
  return Response.json(await db.user.findMany())
}

无需单独后端仓库。

1.17.4 性能默认值高

无需优化也很快。

1.17.5 零配置开发

开箱即用,不需要配置:

  • webpack
  • babel
  • typescript
  • 路由系统
  • 预取逻辑
  • 图片优化
  • 字体优化

1.18 App Router 带来的十个核心能力(总结)

  1. RSC(删除多余 JS)
  2. SSR + Streaming(快速首屏)
  3. 更轻量客户端(use client 显式标记)
  4. 组件内部 await 数据
  5. Route Handlers(API 层内置)
  6. Server Actions(表单-数据库直接连通)
  7. 中间件(租户、权限、地域逻辑)
  8. 自动缓存 + revalidate
  9. Edge Runtime(服务器更近)
  10. 目录结构统一(降低团队成本)

1.19 小结:为什么 App Router 是未来,而 Pages Router 是过去?

Pages Router 最大的限制是:

  • SSR 旧技术
  • no streaming
  • 组件全部进入客户端
  • 数据获取太分散
  • 无法直接访问数据库
  • 缺乏全栈能力

App Router 解决所有问题:

  • RSC → 结构性性能飞跃
  • 服务器优先 → 性能更强
  • 全栈能力 → SaaS/B2B 完美适配
  • Streaming → 体验更流畅
  • 新 API 体系 → 更少心智负担

全世界所有大型团队都在迁移到 App Router 是有理由的。

App Router 不只是 Next.js 的未来,它是 React 全栈开发的未来。

1.20 App Router 带来的最大心智革命:组件内部 async/await

在 App Router 之前,React 中的异步数据获取一直是个反模式:

  • React 不允许组件异步
  • React 不允许直接在组件内部 await
  • 所有数据必须通过“外部函数”传入组件
  • 因为客户端组件只能在浏览器中执行
  • 因此必须用 useEffect 来 fetch

最终导致老 React 项目的典型结构:

function Page() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch("/api/posts").then(res => res.json()).then(setData);
  }, []);

  return (...)
}

但是这种模式有严重问题:

❌ 1. SEO 无法抓到内容(因为内容在 JS 执行后才出现)

❌ 2. 首屏白屏

❌ 3. 客户端多余 JS 执行

❌ 4. 组件首次渲染时 data 为空

❌ 5. 必须写繁琐的状态管理

❌ 6. 每个页面重复写数据加载逻辑

❌ 7. 浏览器必须承担更多计算压力

React 内部对此无能为力——直到 RSC 出现。

1.20.1 服务器组件允许在组件内部直接 await

在 App Router 中你可以这样写:

export default async function Page() {
  const posts = await db.post.findMany();
  return <PostList posts={posts} />;
}

这是过去 10 年不敢想象的。

这个改变带来 7 个革命性结果:

✔ 1. 组件首次渲染就有数据

无状态闪烁问题消失。

✔ 2. 不需要 useEffect

没有副作用,也没有双渲染问题。

✔ 3. 不需要 Redux/AuthStore/DataStore

因为数据分布在组件内部,不需要全局状态。

✔ 4. 不需要 loading 状态管理

使用 loading.tsx 即可。

✔ 5. 不需要 SWR/React Query

服务器自己处理缓存。

✔ 6. 更小的客户端 JS bundle

因为组件默认是服务器组件,不会进客户端打包。

✔ 7. 更自然的代码结构

你可以像写普通后端一样写页面。

1.20.2 组件内 await 是如何运行的?(底层机制)

Next.js 编译器(基于 React Server Compiler)会将:

const posts = await db.post.findMany();

转换为:

  • 在服务器执行
  • 返回一个 RSC Payload
  • 浏览器不执行这段代码
  • 浏览器只渲染结果

而不是:

  • 浏览器下载 JS
  • 浏览器执行 JS
  • 浏览器再发请求
  • 浏览器再渲染

这是直接减少一个完整的网络往返。

1.20.3 为什么组件内 await 比 API fetch 快?

对比一下:

传统方式(老 React)

浏览器 → fetch API → server → database → server → browser

App Router 方式(RSC)

server → database → server → browser

省略了:

  • 浏览器到服务器的请求
  • CORS
  • API 层
  • JSON 序列化/反序列化
  • 再次 hydration
  • 再次 re-render

这是前后端协作方式的根性变革。

1.21 Next.js 的缓存系统:现代 Web 性能的核心

Next.js 有一个极其重要但很多人不了解的系统:

Segment-level caching(片段级缓存)

它通过:

  • fetch cache
  • full page cache
  • RSC cache
  • revalidate() API
  • revalidatePath()
  • revalidateTag()

构建了一个“自动缓存 + 局部更新”的系统。

1.21.1 fetch 缓存(针对数据请求)

你可以这样配置缓存:

await fetch(url, {
  next: { revalidate: 10 }
});

或:

await fetch(url, {
  cache: "no-store"
});

这一切由框架自动处理:

  • 缓存放在哪里
  • 何时失效
  • 缓存 key 如何分配
  • 如何在集群中同步 cache
  • 对 streaming 的影响

作为开发者,你无需自己操心。

1.21.2 全页面缓存 + ISR

App Router 支持现代化 ISR:

  • 访问时发现过期 → 旧内容立即返回
  • 并在后台触发重新生成
  • 用户无感知

代表配置:

export const revalidate = 3600;

或针对 fetch:

fetch("/api/posts", { next: { revalidate: 60 } });

这是大量网站喜欢 Next.js 的原因:

SSR 的灵活性 + SSG 的性能 + ISR 的更新能力。

1.22 Route Handlers:内置 API 层

Route Handlers 允许你在:

app/api/**/route.ts

创建 API。

例如:

export async function GET() {
  const users = await db.user.findMany();
  return Response.json(users);
}

无需 Express/Koa/Fastify。

Route Handlers 能做:

  • REST API
  • GraphQL 端点
  • Webhook 处理
  • 文件上传
  • 鉴权
  • 中间件配合

Route Handlers 的定位:

明确的 API 端点,适合跨客户端、多端调用(Web、Native、第三方合作)。

1.23 Server Actions:比 API Route 更强大的后端函数

Server Actions 是 Next.js 最具代表性的全栈能力之一。

基本形式:

"use server";

export async function createPost(data) {
  await db.post.create({ data });
}

然后在客户端组件内直接调用:

<form action={createPost}>
  <input name="title"/>
  <button type="submit">Create</button>
</form>

Server Actions 的革命性意义在于:

✔ 1. 前端表单可以直接连到数据库

不需要:

  • fetch
  • axios
  • API route
  • JSON body
  • useEffect

✔ 2. Server Action 自动序列化

你无需手写 JSON 处理。

✔ 3. 自动防止 XSS/CSRF

框架处理了服务端函数调用的所有安全问题。

✔ 4. 自动返回表单状态

包括 pending/error 成员。

✔ 5. 最短路径

旧路径:

Browser → API → Server → DB → Server → API → Browser

新路径:

Browser → Server Action → DB → Browser

✔ 6. 可用于乐观更新

和 React 的并发模式完美结合。

1.24 Route Handlers vs Server Actions:如何选择?

场景使用 Server Action
表单提交
登录、注册
写数据库
与 UI 强绑定的逻辑
仅内部调用的函数
场景使用 Route Handler
提供公共 API
第三方 Webhook(Stripe、GitHub)
REST/GraphQL
文件上传/下载
跨平台(Web + Native)

总结:

Server Actions = UI 驱动的后端函数。

Route Handlers = 独立的 API 服务。

1.25 为什么 Next.js 是 2025 年构建 SaaS 的最强框架?

SaaS 项目通常包含:

  • 多租户
  • 权限系统
  • DB 操作
  • RBAC
  • Admin Dashboard
  • 用户信息管理
  • 邀请机制
  • 付费订阅
  • 多语言
  • 全局布局
  • SEO
  • 高性能
  • 大量 UI 模块
  • 数据实时刷新
  • 后端 API
  • 文件上传
  • 国际化
  • 访问控制中间件

这些需求几乎全部内置在 Next.js 的架构里。

下面列出具体原因。

1.25.1 Server Components + DB 直连让开发效率提升数倍

在 SaaS 场景中,数据模型复杂,例如:

  • 用户
  • 租户
  • 应用
  • 权限
  • 角色
  • 订阅
  • 使用额度
  • workspace
  • team
  • integration

传统方式:

前端 → fetch → API server → DB

Next.js 方式:

Server Component → DB

减少大量样板代码(boilerplate)。

1.25.2 App Router 的 layout 系统非常适合后台系统

一个后台系统通常有:

  • 左侧导航栏
  • 顶部导航
  • 内容区
  • Context providers

App Router 的 layout 正好匹配:

app/layout.tsx
app/dashboard/layout.tsx
app/dashboard/page.tsx

这让 UI 架构完全模块化。

1.25.3 Route Handlers 提供多租户 API

结合 Middleware 可以实现:

  • 子域名租户(tenantA.example.com)
  • 路径租户(/tenantA)
  • 自定义域名租户(customer.com)

这是 B2B SaaS 的基本能力。

1.25.4 Server Actions 彻底简化 CRUD

原来需要:

  • 定义 API
  • 定义表单
  • 定义 fetch
  • 定义 useMutation
  • 定义错误处理
  • 定义加载状态
  • 派发状态更新

现在:

<form action={updateSetting}>

即可。

1.25.5 与 Vercel 完美组合用于全球业务

Vercel 的优势:

  • 全球 CDN
  • Edge Functions
  • 自动缓存
  • 全球加速
  • 自动部署
  • 零配置

对 SaaS 来说:

  • KYC
  • GDPR
  • 数据最小化
  • 地域合规
  • 性能指标

都能轻松达标。

1.26 Next.js 是未来 Web 平台的“底座”

总结一下 Next.js 的定位:

  • React 全栈框架
  • 服务器优先
  • RSC 第一实现方
  • 全局缓存层
  • 部署网络(CDN+Edge)集成
  • 最佳 SEO 方案
  • 最佳性能默认值
  • 最佳工程化体验
  • 最适合 SaaS 的框架

现代团队用它不是因为潮流,而是:

它确实是适合 2025 年生产环境的唯一稳定架构。

1.27 Streaming 与 Suspense:Next.js 的即时反馈革命

在 App Router 中,Streaming 是一个默认且核心的能力。

Streaming 的含义是:

服务器不必等整个页面渲染完,就可以把已完成的部分实时推送给浏览器。

这与传统 SSR 的区别巨大。

1.27.1 传统 SSR 的缺点:必须等待所有数据加载完成

旧 SSR 流程:

1. 服务端开始渲染页面
2. 等待所有数据准备好
3. 一次性输出 HTML
4. 浏览器开始渲染
5. 浏览器开始执行 JS
6. hydrating

如果页面中:

  • 有一个慢接口
  • 有一个慢 SQL 查询
  • 有一个必须等待的外部 API

整个页面都会被阻塞。

用户体验就是:

  • 一直白屏
  • 等 3 秒
  • 页面才闪现出来

这在电商、社交、资讯类站点非常糟糕。

1.27.2 App Router 的 Streaming:页面一部分一部分“流”出来

Next.js 的 Streaming 做了两件事:

✔ (1)布局和静态部分先显示

✔ (2)慢的数据稍后加载

像这样:

Header → Sidebar → Hero → Loading...

然后:

Loading... → 替换成真实数据

这让用户能:

  • 立即看到页面结构
  • 立即能进行交互
  • 不需要等慢请求
  • 所有内容按需显示

体验更加接近原生 App。

1.27.3 Suspense 是 Streaming 的基础

React Suspense 的意义是:

提供“占位 + 延迟 + 异步刷新”机制。

例如:

<Suspense fallback={<Loading />}>
  <SlowComponent />
</Suspense>

这表示:

  • 服务端立即发送 fallback
  • 当 SlowComponent 数据准备好后再替换

App Router 内部大量使用 Suspense:

  • loading.tsx 自动使用 Suspense
  • page.tsxlayout.tsx 会分片渲染
  • 嵌套路由会独立 streaming
  • 数据等待不会阻塞整个页面

1.27.4 App Router 如何处理瀑布式渲染问题?

传统 SSR 的致命问题之一是:

瀑布式渲染(Waterfall rendering)

示例:

  • 页面请求 A,页面等 A 返回
  • 页面渲染 B,页面等 B 返回
  • 页面渲染 C,页面等 C 返回

每个阶段依赖上一个阶段 → 时间不断累积 → 用户等待变长。

App Router 解决方式:

✔ Server Components 可以并行渲染

✔ fetch 缓存避免重复访问

✔ Suspense 局部渲染

✔ Streaming 可以让已完成部分先展示

最终结果是:

不需要等待所有组件的数据准备好,渲染过程不再线性阻塞。

1.28 Layout(布局)系统:App Router 最具生产力的能力之一

App Router 中 layout 是一等公民:

app/layout.tsx
app/dashboard/layout.tsx
app/dashboard/settings/layout.tsx

Layout 的意义远比想象中大得多。

1.28.1 Layout 提供结构化 UI 的天然能力

例如,一个 SaaS 后台常见布局:

  • 顶栏
  • 侧栏
  • 内容区
  • 面包屑
  • 用户信息
  • 全局 provider

这些都应该放在 layout。

例如:

export default function DashboardLayout({ children }) {
  return (
    <div className="dashboard">
      <Sidebar />
      <main>{children}</main>
    </div>
  );
}

这意味着:

  • Sidebar 不会重复渲染
  • Layout 能缓存
  • Layout 也能 Streaming
  • 页面跳转时 Layout 保持不变
  • 用户体验更流畅

1.28.2 Layout 缓存是性能提升的关键

旧模式:

  • 每次路由变化都会重新渲染整个页面
  • 包括导航栏、侧边栏、布局结构等

App Router 模式:

  • Layout 可以保持稳定(persist)
  • 只有 children(页面内容)更新
  • 多级嵌套布局形成一个强大的渲染树

这使得后台系统:

  • 路由切换瞬间完成
  • 缓存命中率极高
  • 页面结构不会闪烁

体验类似原生应用。

1.28.3 多级布局让复杂网站更易维护

示例结构:

app/
  layout.tsx        # 全局
  dashboard/
    layout.tsx      # 管理后台
    analytics/
      layout.tsx    # 分析模块
      page.tsx

每个模块有独立的 UI 结构与逻辑。

结合 Streaming:

  • 上层布局即时展示
  • 子布局逐步加载
  • 最终页面数据异步填充

这让大规模应用开发非常顺畅。

1.29 Middleware:Next.js 的“边缘控制层”

Middleware 运行位置:

在请求到达路由之前,在边缘节点上执行。

运行环境:

  • Edge Runtime(非常轻量)
  • 可在全球离用户最近的位置执行
  • 不依赖 Node.js API

适合:

  • 权限验证
  • 重定向
  • 路由改写
  • 国际化
  • A/B Testing
  • 多租户解析
  • 域名映射

典型示例:

import { NextResponse } from "next/server";

export function middleware(req) {
  const url = req.nextUrl;

  if (!req.cookies.get("token")) {
    url.pathname = "/login";
    return NextResponse.redirect(url);
  }

  return NextResponse.next();
}

1.29.1 Middleware 特别适用于多租户 SaaS

例如判断租户域名:

customerA.example.com → tenantId = 1
customerB.example.com → tenantId = 2

通过 Middleware:

export function middleware(req) {
  const hostname = req.nextUrl.hostname;
  const tenant = getTenantByHostname(hostname);

  req.headers.set("x-tenant-id", tenant.id);
  return NextResponse.next();
}

之后所有 Server Components 都能读取 tenantId。

这使 Next.js 成为构建多租户应用的理想框架。

1.30 Edge Runtime:全球用户体验的质变

Edge Runtime 是 Next.js 的另一核心能力。

Edge 的意义:

  • 更靠近用户
  • 延迟从 100ms 降至 5ms
  • 适合鉴权、重定向、cookie 校验

Next.js 支持:

  • Edge Middleware
  • Edge Route Handlers
  • Edge Server Actions(实验)

Edge 不是代替服务器,而是补充:

“把轻量逻辑推到全球边缘,提高响应速度。”

1.30.1 什么逻辑适合 Edge?

  • 用户登录验证
  • session 校验
  • 多租户域名识别
  • 地域限制(如 GDPR)
  • Bot 检测
  • A/B 测试
  • 防爬虫逻辑

这些都比放在传统服务器更合适。

1.31 Next.js 的“组合式性能系统”

Next.js 的性能提升不是某一个能力,而是系统性协同:

✔ 1. Server Components → 减少 JS
✔ 2. Streaming → 更快首屏
✔ 3. Suspense → 局部渲染
✔ 4. Layout 缓存 → 路由更快
✔ 5. fetch 缓存 → 数据加载更快
✔ 6. ISR → 静态性能 + 动态数据
✔ 7. Edge → 地理延迟更低
✔ 8. 自动代码拆分 → bundle 更小
✔ 9. next/image → 图片优化
✔ 10. next/font → 字体优化

这些能力加起来,使得 Next.js 成为:

唯一真正生产可用、性能极强、可扩展、可维护的 React 全栈框架。

1.33 App Router 如何构建大型可维护应用(B2B / SaaS 的真正价值)

大型 Web 应用通常包含:

  • 多模块(dashboard / analytics / billing / team / settings)
  • 多层嵌套(团队 → 项目 → 资源)
  • 多级布局(全局 / 区域 / 页面)
  • 多数据源(数据库 + 外部 API + 内部服务)
  • 多级缓存(浏览器 → CDN → Server → DB)
  • 多租户逻辑(tenant_id)
  • 鉴权系统(RBAC / ABAC)
  • 国际化
  • 表单处理
  • 实时更新(WebSocket / SSE)
  • 超多页面(数百至数千个)

传统 React + React Router 的架构缺乏:

  • 内置路由层
  • 内置数据层
  • 内置缓存系统
  • 内置 SSR 系统
  • 统一运行时
  • 全局布局层
  • Streaming
  • 多级缓存
  • 多级 loading
  • 全局错误边界
  • 中间件 / Edge 层

构建大型系统时会迅速崩溃。

1.33.1 App Router 的模块化天然适配大型系统

通过目录即可表达系统结构:

app/
dashboard/
layout.tsx
page.tsx
projects/
layout.tsx
page.tsx
[id]/
page.tsx
analytics/
layout.tsx
page.tsx

每个模块自成结构:

  • layout
  • page
  • loading
  • error
  • not-found
  • API(route.ts)

开发者只关注模块即可,天然分层。

这比传统方式:

src/
pages/
components/
api/
utils/
contexts/
stores/

要清晰得多。

1.33.2 App Router 的“局部渲染”适合海量页面

传统 React Router:

  • 路由切换时重新卸载整个页面
  • 侧边栏/头部必须重新渲染
  • UI 闪烁
  • 大型后台体验糟糕

App Router:

  • layout.tsx 保持不变
  • children 替换
  • 布局缓存
  • Streaming 流式渲染
  • 用户几乎感觉不到页面跳转

这使得 Next.js 比 Vue/Nuxt 在大型后台上更自然。

1.33.3 App Router 的“分层数据加载”是大型产品的必需

在大型 B2B 后台中,典型的数据依赖链:

  • 全局用户信息(身份验证、租户信息)
  • 团队级数据
  • 项目级数据
  • 页面级数据
  • 组件级数据

传统 SPA:

  • 必须在 useEffect + Redux 中手动处理多层数据
  • 数据冲突、脏读频繁
  • 页面渲染复杂度极高

App Router:

  • 高层 layout 加载高层数据
  • 低层 layout 加载低层数据
  • page.tsx 加载页面数据
  • 使用 Suspense 和 Streaming
  • 全局缓存自动管理重复请求

最终形成清晰自然的数据层:

layout
└── layout
└── layout
└── page (最终 UI)

大型系统开发不再混乱。

1.34 Next.js 渲染流水线(Render Pipeline)深度解析

要真正理解 Next.js 的能力,必须理解它的渲染流水线。

App Router 的渲染流水线可分为几个阶段:

1. Routing(路由解析)
2. Loader(读取 layout/page 组件)
3. RSC Processing(服务器组件编译)
4. Data Fetching(fetch 与 DB 访问)
5. Caching(缓存层)
6. Streaming(流式输出 HTML + RSC Payload)
7. Hydration(仅客户端组件进行 hydration)
8. Interactivity(页面可交互)

下面逐一深度解析。

1.34.1 路由解析阶段(Routing)

Next.js 会通过文件系统映射出完整的路由树:

app/
a/
layout.tsx
page.tsx
b/
page.tsx

Next.js 按路由递归构建:

/ → layout → page
/a → root layout → a layout → a page
/b → root layout → b page

路由解析是整个渲染的起点。

1.34.2 RSC 编译阶段(React Server Compiler)

这是 Next.js “黑科技”最多的阶段。

Next.js 会将 Server Component 编译为:

  • 可以在服务器执行的函数
  • RSC Payload(wire format)
  • 客户端组件的引用点

例如:

export default function Page() {
  return <Button />;
}

编译器会决定:

  • <Button /> 是否是客户端组件
  • 是否需要打包 JS
  • 是否需要 hydration
  • 是否需要 Suspense 包裹
  • 是否可以 streaming

这是 React 生态中最底层的技术之一。

1.34.3 数据加载阶段(Data Fetching)

App Router 支持:

  • 组件内 await
  • fetch 缓存
  • DB 直连
  • revalidate
  • retry
  • streaming 中等待数据

Next.js 会自动分析依赖图:

例如:

Page → fetch → DB
Layout → fetch → API

这些请求会:

  • 并行执行
  • 自动缓存
  • 自动 dedupe(去重)

比传统 React + useEffect 效率高得多。

1.34.4 缓存阶段(Caching)

这是 Next.js 的灵魂部分。

缓存类型包括:

• RSC cache

缓存组件渲染结果。

• fetch cache

缓存数据获取结果。

• Full Page cache

缓存整个页面输出。

• Route Cache

缓存 API route 或路由处理器的结果。

• CDN cache

由 Vercel 或 Cloudflare 储存的静态内容。

缓存算法会根据:

  • fetch 配置(cache / next.revalidate)
  • 动态/静态标记
  • layout 内组件状态
  • dynamic = “force-dynamic”
  • cookies 的使用情况
  • searchParams
  • headers

智能决定是否缓存。

这是 Next.js 区别于 Vite/Nuxt/Remix 的关键能力。

1.34.5 Streaming 阶段(流式渲染)

当组件树部分完成渲染时:

  • HTML 会立即 send() 给浏览器
  • RSC Payload 会在后续补全
  • loading.tsx 会自动作为 fallback

用户在 100ms 内即可看到页面框架。

在 2023–2025 年,Streaming 是大型网站性能的主要突破点。

1.34.6 Hydration 阶段(仅客户端组件)

传统 React:

  • 必须 hydration 整个页面

App Router:

  • 仅 hydration 标记为 "use client" 的组件
  • 页面 90%+ 的 UI 都不需要 hydration
  • 大幅降低 JS 执行量与 CPU 占用

这也是 Next.js 比 Nuxt/Remix 更快的原因。

1.35 Next.js 缓存系统的深度分析

Next.js 的缓存系统是其最具工程价值的模块之一,它具有:

  • 自动缓存
  • 自动无效化
  • 自动再验证(ISR)
  • 自动 dedupe
  • 自动短路(直接返回缓存)
  • 自动 Streaming
  • 自动 CDN 集成

这是生产环境性能的关键。

1.35.1 fetch 缓存的三种模式

模式 A:静态缓存(default)

fetch(url) // 默认静态缓存

模式 B:过期缓存(ISR)

fetch(url, { next: { revalidate: 60 } })

模式 C:不缓存(SSR 动态)

fetch(url, { cache: "no-store" })

开发者只需一个配置即可决定页面性能策略。

1.35.2 Next.js 自动判断页面是否可缓存

若组件中出现:

  • cookies()
  • headers()
  • searchParams
  • crypto 随机数
  • any IO without cached fetch

Next.js 会自动标记为:

dynamic = "force-dynamic"

并确保:

  • 页面不被静态生成
  • 页面不被缓存
  • 页面每次请求都执行

无需开发者介入。

这保护了开发者不犯错。

1.35.3 页面级缓存(Full Page Cache)

SSG 页面示例:

export const revalidate = 3600;

Next.js 会生成缓存版本:

  • 位于 Vercel CDN
  • 一旦失效自动触发后台 re-generate
  • 用户永远不会等待重建
  • 旧内容立即可用
  • 新内容之后更新

这让 Next.js 网站“既快又动态”。

1.36 框架“控制反转”(Inversion of Control)带来的优势

在传统 React 中,开发者需要控制:

  • 数据加载
  • 数据缓存
  • 更新逻辑
  • 错误处理
  • 状态管理
  • API 调用
  • 路由表

这些“控制”导致大量工程复杂度。

Next.js 的 App Router 的核心理念是:

把复杂的事情交给框架,把业务留给开发者。

框架负责:

  • 渲染模型
  • 缓存策略
  • Streaming
  • Suspense
  • 路由
  • SEO
  • 布局持久化
  • 数据去重
  • Hydration
  • 性能优化

开发者只负责:

  • 组件
  • UI
  • 业务逻辑

这种理念与 Ruby on Rails 的精神一致:

框架应尽可能替开发者做事,而不是让开发者处理基础设施。

1.37 Next.js 作为“统一运行时”是什么概念?

在 App Router 结构下:

  • 页面
  • 后端函数
  • API
  • 中间件
  • Edge
  • Streaming
  • 缓存
  • Layout
  • 模板
  • 国际化
  • 资源优化

全部运行在统一的 Next.js Runtime 中。

你不再需要:

  • Node 服务器
  • Express/Koa
  • 前端打包
  • SSR 服务
  • 独立静态服务器
  • Webpack 配置
  • 特定中间层(BFF)
  • CDN 配置
  • API Routes 外层代理

Next.js 替你管理一切。

这使得 Web 架构回归简单。

1.38 Next.js 是如何改变开发者体验(DX)的?

现代框架比拼的不是语法,而是:

整个团队的生产力和幸福感。

Next.js 提供:

✔ 没有 Webpack 配置
✔ 没有路由配置
✔ 没有 hydration 管理
✔ 没有数据重复请求问题
✔ 没有 API 冗余逻辑
✔ 没有 Redux boilerplate
✔ 没有 useEffect 瀑布

最终使得代码从复杂变为简单:

1.38.1 老写法(繁琐、臃肿、难维护)

function Page() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("/api/items")
      .then(res => res.json())
      .then(setData);
  }, []);

  if (!data) return <Loading />;
  return <ItemList items={data} />;
}

1.38.2 新写法(清晰、自然、优雅)

export default async function Page() {
  const items = await db.item.findMany();
  return <ItemList items={items} />;
}

这是工程性的质变。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页