next 精选推荐

App Router vs Pages Router 选型指南:架构差异与迁移策略

HTMLPAGE 团队
16 分钟阅读

深入对比 Next.js App Router 和 Pages Router 的架构差异、性能特点和适用场景,帮助团队做出明智的技术选型决策

#App Router #Pages Router #技术选型 #架构设计

两种路由器的前世今生

Next.js 的路由系统经历了一次根本性的重构。Pages Router 陪伴开发者走过了六年,建立了稳固的心智模型;App Router 则是 Vercel 团队对 React 未来方向的押注,代表着一种全新的开发范式。

理解两者的差异,不仅是技术选型的需要,更是理解现代前端演进方向的窗口。

架构层面的根本差异

渲染模型

Pages Router 的渲染模型相对简单:

  • 每个页面是一个独立的入口点
  • 数据获取通过 getServerSideProps / getStaticProps 在页面级别完成
  • 客户端和服务端的边界清晰:服务端准备数据,客户端渲染 UI

App Router 引入了组件级别的服务端渲染:

  • 默认所有组件在服务端渲染
  • 需要客户端交互的组件用 'use client' 标记
  • 数据获取可以发生在任意组件层级

这看起来只是灵活性的提升,但实际上改变了整个应用的思考方式。

布局系统

Pages Router 的布局是"自己搞定"的:

  • 通过 _app.js 定义全局布局
  • 页面级布局需要手动组合高阶组件
  • 导航时布局会重新渲染

App Router 内置了嵌套布局:

  • layout.js 文件自动创建布局层级
  • 导航时布局状态保持,只重新渲染变化的部分
  • 天然支持并行路由和拦截路由

对于复杂的多层级导航,App Router 的布局系统省去了大量样板代码。

数据获取

这是两种架构差异最明显的地方:

特性Pages RouterApp Router
数据获取位置页面顶层任意组件
获取方式专用函数async 组件 / fetch
缓存控制手动管理框架内置
流式渲染不支持原生支持
并行数据获取需手动处理自动并行

App Router 中,一个组件直接 await fetch(...) 就能获取数据,无需在页面顶层统一处理再层层传递。这种"就近获取"的模式让组件更加自包含。

性能特点对比

首屏加载

Pages Router

  • 所有页面级代码打包在一起
  • 数据获取阻塞页面渲染
  • 典型的"白屏 → 完整页面"体验

App Router

  • Server Components 不增加客户端 bundle
  • 支持流式渲染,可以渐进展示
  • Suspense 边界内的内容独立加载

实测数据显示,相同功能的页面,App Router 版本的 JavaScript bundle 大小通常减少 20-40%。但这个优势需要正确使用 Server Components 才能体现。

导航性能

Pages Router 的导航:

  1. 触发路由变化
  2. 下载目标页面代码(如果没缓存)
  3. 执行数据获取(getServerSideProps
  4. 渲染新页面

App Router 的导航:

  1. 触发路由变化
  2. 复用不变的布局
  3. 流式加载变化的部分
  4. 渐进渲染

关键差异在于布局复用。一个典型的后台应用,侧边栏和顶部导航在页面切换时保持不变,只有内容区更新。App Router 天然支持这种模式,Pages Router 需要额外处理。

缓存与重验证

Pages Router 的缓存完全自理,你可以用 SWR、React Query 等库来管理。

App Router 内置了多层缓存:

  • Request Memoization:同一渲染周期内相同请求自动去重
  • Data Cache:fetch 结果持久化缓存
  • Full Route Cache:静态路由的完整 HTML 缓存
  • Router Cache:客户端导航的路由缓存

这套缓存系统很强大,但也带来了学习曲线。Next.js 15 已经简化了默认行为,但理解各层缓存的工作方式仍然必要。

开发体验差异

心智模型

Pages Router 的心智模型接近传统 MVC:

  • 路由文件 = 控制器
  • 数据获取 = 查询数据
  • 返回 JSX = 渲染视图

这个模型直观,容易上手,后端开发者也能快速理解。

App Router 的心智模型更接近组件化:

  • 每个组件是独立的渲染单元
  • 数据和 UI 就近结合
  • 服务端/客户端边界需要主动划分

这种模型更灵活,但也更抽象,需要一定的适应期。

调试体验

Pages Router 的调试相对简单:

  • 清晰的服务端/客户端分界
  • 错误信息直接定位到数据获取函数
  • 传统的 console.log 工作良好

App Router 的调试更复杂:

  • Server Components 的 console.log 在终端输出
  • 客户端组件的 log 在浏览器控制台
  • 水合错误的排查需要理解 RSC 协议

不过 Next.js 15 已经大幅改进了错误提示,调试体验比早期版本好很多。

生态兼容性

Pages Router 几乎兼容所有 React 生态:

  • 任何客户端状态管理库
  • 任何 CSS-in-JS 方案
  • 任何表单库

App Router 有一些限制:

  • 某些 CSS-in-JS 库需要适配(运行时生成样式的方案)
  • Context 的使用需要注意服务端/客户端边界
  • 部分库尚未适配 Server Components

这个差距在逐渐缩小,主流库都在积极适配。但如果你的项目依赖某个小众库,升级前需要验证。

选型决策框架

选择 Pages Router 的情况

团队熟悉度:如果团队对 Pages Router 已经很熟练,且项目时间紧张,继续使用是务实的选择。

简单的页面应用:营销网站、文档站点等页面结构简单的项目,Pages Router 足够胜任,App Router 的优势体现不明显。

深度依赖特定库:如果项目严重依赖某个尚未适配 App Router 的库,强行迁移的成本可能很高。

稳定性优先:App Router 虽然已经稳定,但相比 Pages Router 六年的积累,边缘情况的处理可能还有差距。对于金融、医疗等对稳定性要求极高的场景,Pages Router 是更保守的选择。

选择 App Router 的情况

复杂的嵌套布局:如果应用有多层嵌套布局、多个独立的内容区域,App Router 的布局系统能省很多代码。

性能敏感:需要精细控制哪些代码在服务端运行、哪些在客户端运行,追求最小的 JavaScript bundle。

流式渲染需求:希望页面渐进加载,提升用户感知速度。

长期投资:新项目打算维护多年,希望跟上 React 和 Next.js 的演进方向。

决策清单

回答以下问题,帮助做出选择:

  1. 项目是新建还是现有项目改造?
  2. 团队对 Server Components 的理解程度?
  3. 有没有严重依赖的第三方库?
  4. 应用的布局复杂度如何?
  5. 对首屏性能的要求有多高?
  6. 项目的预期生命周期是多长?

如果多数答案指向"新项目、愿意学习、无特殊依赖、布局复杂、性能敏感、长期维护",App Router 是更好的选择;反之则 Pages Router 更稳妥。

迁移策略

如果决定从 Pages Router 迁移到 App Router,以下是经过验证的策略。

渐进式迁移

Next.js 支持两种路由器并存,这是官方推荐的迁移方式:

  1. 保持 pages 目录:现有页面继续工作
  2. 新增 app 目录:新功能用 App Router 开发
  3. 逐页迁移:优先迁移独立的、不涉及复杂状态的页面
  4. 最后处理共享逻辑:布局、中间件、状态管理

关键原则:不要一次性重写。迁移是高风险操作,渐进式才是稳妥之道。

迁移清单

路由文件映射

  • pages/index.jsapp/page.js
  • pages/about.jsapp/about/page.js
  • pages/blog/[slug].jsapp/blog/[slug]/page.js

数据获取改造

  • getServerSideProps → async 组件 + fetch
  • getStaticProps → async 组件 + fetch + 缓存配置
  • getStaticPathsgenerateStaticParams

API 路由

  • pages/api/*.jsapp/api/*/route.js
  • 函数签名从 (req, res) 改为 (request)

布局提取

  • _app.js 中的全局布局 → app/layout.js
  • 页面级布局 → 对应目录的 layout.js

常见迁移陷阱

CSS-in-JS 问题:Emotion、styled-components 等库需要特殊配置才能在 App Router 中工作。提前查阅官方文档。

状态提升问题:Server Components 不能使用 hooks,原来的状态逻辑可能需要重构,把状态下沉到 Client Components。

第三方脚本:原来在 _document.js 中添加的第三方脚本,需要迁移到 app/layout.js 或使用 next/script

404 和错误页面pages/404.js 变成 app/not-found.jspages/_error.js 变成 app/error.js

面向未来的思考

React 团队明确表示,Server Components 是 React 的未来方向。Next.js 的 App Router 是目前 Server Components 最成熟的生产级实现。

从这个角度看,学习 App Router 不仅是学习一个路由系统,而是学习 React 的下一个十年

但技术选型不是追热点,而是解决实际问题。如果 Pages Router 能很好地满足需求,没必要为了"新"而迁移。等团队有精力、有需求的时候再动,比仓促迁移踩一堆坑要明智得多。

总结

维度Pages RouterApp Router
学习曲线平缓陡峭
心智模型MVC 风格组件化
布局能力基础强大
数据获取页面级组件级
性能上限中等
生态兼容完善逐步完善
未来趋势维护模式主推方向

最终建议:新项目优先考虑 App Router,现有项目视情况渐进迁移。无论选择哪个,都要深入理解其设计理念,而不只是照着文档抄代码。


相关文章推荐: