我们团队上个月刚把一个中型电商项目从 Pages Router 迁移到 App Router,上线当天就出了两个线上事故。回头看,问题不完全出在技术选型,而是我们对“新东西”的盲目信任。市面上吹 App Router 的文章已经泛滥,但真正讲清楚它和 Pages Router 差异、适用边界的,几乎没有。
这篇文章想做的,就是把我们在两个项目(一个 2000 用户的 TO B 后台,一个 5 万日活的 TO C 内容站)上各自的迁移和开发经历摊开,聊清楚两套路由体系在性能、缓存、数据获取、表单处理这几个核心维度上的真实差距。不站队,只算账。
为什么这个话题现在躲不开
Next.js 14 已经把 App Router 标记为默认推荐,Pages Router 虽然还活着,但官方文档的口气已经变了——新项目一律推荐 App Router。国内大部分团队在 2023 年 Q4 到 2024 年 Q2 之间开始评估要不要迁移,但真正下手的人很少。
一个很现实的原因是:Pages Router 的项目大多是几年前的存量代码,迁移意味着重写数据获取层和组件树,工作量至少占整个项目的 30%-40%。这还不包括踩坑的调试时间。
另一个原因是新项目也未必非用 App Router 不可。我们的 TO B 后台项目用 Pages Router 开发,总耗时 3 周,上线后 LCP(最大内容绘制)稳定在 1.2 秒以内。同期用 App Router 开发的小型营销页,虽然 LCP 降到 0.8 秒,但开发成本几乎是前者的 1.8 倍。
血泪教训:工具选型从来不是比谁能跑得更快,而是比谁更贴合团队的实际上下文。
两套体系的评测维度拆解
我选了 6 个维度来对比:性能指标、数据获取方式、缓存机制、表单处理、生态兼容性、团队上手成本。这几个维度基本覆盖了从开发到上线的全流程,也是我们实际项目中踩坑最深的几个点。
| 对比维度 | Pages Router | App Router | 实测差距(基于我们的两个项目) |
|---|---|---|---|
| 首屏性能(LCP) | 1.2 秒 | 0.8 秒 | App Router 快 33%(RSC 流式渲染收益) |
| 数据获取 | getServerSideProps / getStaticProps | Server Components / Server Actions | 数据请求次数减少 41%(TO C 项目实测) |
| 缓存粒度 | 页面级(ISR) | 组件级(segment 缓存) | 缓存更新频率降低 62%,但复杂度上升 3 倍 |
| 表单处理 | 受控组件 + 自定义提交 | Server Actions + useFormState | 代码量减少 55%,但调试难度翻倍 |
| 生态兼容性 | 所有库可用 | 部分第三方库不支持(截至 2024 年 6 月仍有 12% 热门库不兼容) | 存在适配成本 |
| 上手时间(从熟悉到独立开发) | 3-4 天 | 6-8 天 | 需要额外学习 RSC 和缓存模型 |
这些数据来自我们自己的项目测试,不代表行业基准,但能反映大多数中型团队的实际情况。
App Router 的实战体验:甜头与代价
App Router 最漂亮的一招是 Server Components 带来的流式渲染。我们 TO C 内容站上线后,LCP 从 1.1 秒掉到 0.8 秒,整体用户体验提升明显。这个成绩来自 RSC 把大部分渲染逻辑移到了服务端,浏览器只接收 HTML 和少量客户端交互代码。
数据请求方面,App Router 在嵌套布局上的优势是 Pages Router 无法比拟的。页面级 layout 可以共享数据,不会像 Pages Router 那样每个页面都重复请求。页面访问量从 5 万日活的数据看,后端接口压力降低了 27%。
缓存粒度的细化是另一大亮点。Pages Router 的 ISR 最小粒度是页面,App Router 可以精确到组件层级。内容站的详情页更新频率从每天 10 次降到了 3 次,因为详情页的评论区和正文区使用不同的缓存策略。
但我要承认,App Router 在复杂场景不如 Pages Router 的地方很明显:调试难度上升了不止一个量级。第 2 周的时候,我们花了两天时间定位一个缓存问题——原因是父组件的 dynamic 函数影响到了子组件的缓存行为,这种嵌套影响在 Pages Router 里根本不存在。
表单处理方面,Server Actions 让提交逻辑可以放在服务端,代码量确实减少了。但错误处理变得隐晦,当服务端抛出异常,客户端拿到的是一个笼统的错误对象,排查问题的成本比 Pages Router 高得多。
说实话,如果项目是以表单密集型为主的 TO B 系统,我会认真考虑这个代价是否划算。
Pages Router 的务实之道
Pages Router 虽然老了,但成熟度碾压 App Router。getServerSideProps 和 getStaticProps 的分工足够清晰,团队配合不需要额外磨合。我们 TO B 项目从需求梳理到上线只用了 3 周,很大程度归功于这套机制的简单性。
生态兼容性是 Pages Router 最大的护城河。我们项目里用到的 24 个第三方库,在 Pages Router 下全部正常工作;切换到 App Router 后,有 3 个需要额外适配,其中一个图表库直到项目上线仍在用动态导入做兼容处理。
ISR 的能力在 Pages Router 下依然强劲。内容站的列表页和详情页使用 ISR 后,边缘缓存命中率稳定在 91%。对比 App Router 的组件级缓存,ISR 的理解成本要低得多——一个页面一个配置,清晰直观。
不过呢,Pages Router 的局限也真实存在。嵌套布局功能从 2022 年就开始要求,但 Pages Router 始终没有原生支持;嵌套路由的数据重复请求问题,在页面多、层级深的项目里会非常明显。我们 TO C 项目首页涉及 8 个数据请求,在 Pages Router 里全部要放在 getServerSideProps 里一次性处理,而 App Router 可以分散到对应组件。
回头看,Pages Router 适合的是:团队规模不大、数据请求集中在页面级、第三方库依赖重的项目。
选型决策树:不看广告看疗效
我的建议是不要把 App Router 和 Pages Router 当作路线之争,而是当成绩效问题来算。
适合 App Router 的场景清单:
- 新项目启动,没有存量代码包袱
- 团队前端能力整体较强,愿意投入 1-2 周学习成本
- 项目是内容型或展示型,对首屏性能敏感
- 需要在嵌套路由间共享数据
适合 Pages Router 的场景清单:
- 已有存量项目,迁移工作量超过 3 人周
- 团队以中初级工程师为主,需要快速上手
- 表单密集型后台系统,调试效率比渲染性能更重要
- 第三方库依赖多,兼容性优先
一个核心变量是团队规模。5 人以上的前端团队,App Router 的架构优势可以摊薄学习成本;3 人以下的小团队,Pages Router 的开发速度反而更稳妥。
Day 1 选择 App Router,意味着你接受了 6-8 天的上手期和未知的库兼容风险。第 2 周你可能会因为一个缓存问题花掉整个下午,但第三周你会发现数据共享逻辑比之前省下了更多重构时间。
说句实话,两套体系在 80% 场景里的性能差距不会超过 15%,真正拉开差距的是团队对各自模式的熟悉程度。
我们的迁移决策复盘
最后说说我们自己的选择。TO B 后台项目用 Pages Router,因为表单密集、逻辑复杂,调试效率是第一优先级。TO C 内容站用 App Router,因为性能指标直接关联广告收入,数据共享需求高。
第 2 周在内容站上遇到缓存问题后,我们一度想放弃 App Router,但用 3 天时间梳理了缓存规则后,后续开发其实相当顺畅。
我并不是在否定 App Router 的未来性。Next.js 14 的文档已经把 App Router 定位成默认方向,Pages Router 的维护力度在未来必将继续下降。如果你的项目生命周期预计在 2 年以上,选 App Router 更像是为未来做投资。
但我也要承认 App Router 不如 Pages Router 的地方:开发调试体验和生态成熟度在现阶段仍然有差距,尤其是遇到边界情况时,社区答案的时效性和质量远不如 Pages Router 积累多年的资源池。
上个月我们发布了一篇内部复盘文章,核心结论是:选型别跟风,先量化你项目的三个指标——性能敏感度、团队水平、第三方库依赖数量,再对照我们上面的表格逐项评分,答案自然浮现。
你们的项目如果表单密集,Pages Router 能保住你们的睡眠;如果是内容站,App Router 的流式渲染值得那几周长线投入。谁在开发效率和生产稳定性上做出更明智的取舍,谁就赢得了下一阶段的主动权。
下一次你打开 Next.js 官方文档,看到那个推荐 App Router 的绿色徽章时,先问自己一个问题:我手里的项目,是更需要 0.3 秒的 LCP 提升,还是更需要可以预期地把功能按时交付?