Next.js Parallel Routes:是不是过度设计?它到底解决了 Layout 解决不了的什么问题?
在学习 Next.js App Router 时,很多开发者(包括我自己)都会对着文档里的 Parallel Routes (并行路由) 产生深深的怀疑:
“这不就是把组件拆开来写吗?我直接在
page.js里引入<User />和<Analytics />组件,再包一个Suspense,效果不是一样吗?为什么要搞这么复杂的@folder文件结构?”
如果你也有这个疑问,这篇文章就是为你写的。
Layout (布局) 和 Parallel Routes 看起来都在做“页面拼接”的事,但它们的底层逻辑完全不同。Parallel Routes 并不是为了解决“布局”问题,而是为了解决 “路由状态管理” 的难题。
以下是 Parallel Routes 真正解决的三个 Layout 和普通组件无法搞定的核心问题。
1. 核心痛点:解决“牵一发而动全身”的路由跳转
场景:一个复杂的后台仪表盘。左侧是“团队列表”,右侧是“数据详情”。
需求:点击左侧列表中的 Team B,右侧 URL 变为 /team-b,更新详情。
❌ 普通 Layout/Page 的局限
在传统的路由逻辑中,URL 是唯一的“指挥棒”。当你从 /team-a 跳转到 /team-b 时,Next.js 默认认为你切换了页面。
- 后果:尽管你的左侧列表看起来没变,但 React 可能会重新挂载(Remount)整个页面树,或者至少触发更新。
- 体验崩溃:如果你刚才在左侧列表滚动到了第 50 行,或者折叠了某个菜单,跳转后这些临时状态(UI State) 全部丢失,列表弹回顶部。
✅ Parallel Routes 的解法
Parallel Routes 允许你在同一个 Layout 下定义多个独立的“迷你路由槽”(Slots)。
- 当你只改变
@details插槽的路由参数时,Next.js 引擎会**“冻结”**@list插槽。 - 结果:右侧在加载新数据,左侧列表纹丝不动(不卸载、不重绘、滚动条位置保留)。这种体验就像原生 App 一样丝滑,而 Layout 做不到这一点。
2. 杀手级应用:带 URL 的模态框 (URL-Driven Modals)
这是 Parallel Routes 最不可替代的场景,通常配合拦截路由(Intercepting Routes)使用。
场景:Instagram/Twitter 的照片流。在首页点击照片,弹窗显示详情,背景依然是首页。
❌ 普通 Layout 的死穴
Layout 是分层的,但 Page 是排他的。
- 如果你跳转到
/photo/123,Next.js 会卸载首页组件,挂载详情页组件。 - 后果:背景(首页)消失了,变成了一个白底的详情页。你无法在“保留上一页作为背景”的同时“改变 URL”。
✅ Parallel Routes 的解法
Parallel Routes 允许你在同一个 URL 下同时渲染两层内容:
- @children:继续渲染首页(作为背景)。
- @modal:渲染照片弹窗(覆盖在上面)。
这让你既拥有了 SPA 的体验(不刷新、保留上下文),又拥有了 MPA 的能力(URL 变了,可以直接复制分享链接)。
3. 服务端视角的“条件渲染” (Server-Side Conditional UI)
场景:一个页面,根据用户角色(Admin vs User)显示不同的板块。
❌ 传统组件写法
你可能会在组件里写大量的 if (isAdmin) return <AdminPanel />。
- 隐患:即使不渲染,组件代码可能依然被打包到了客户端 Bundle 中。且逻辑耦合在组件内部,不易维护。
✅ Parallel Routes 的解法
利用 layout.js 和 default.js。
- 你可以在 Layout 的服务端代码中直接决定是否渲染
{admin}插槽。 - 如果是普通用户,Layout 直接忽略该插槽。Next.js 根本不会去执行
@admin/page.js下的代码(包括数据库查询)。 - 优势:这带来了更好的安全性(敏感逻辑完全不发送给客户端)和性能(更小的 Bundle,更少的请求)。
4. 为什么不用 Hash Router (#)?
有人会问:“想保留状态和背景,我用 window.location.hash (例如 /feed#photo-123) 不也行吗?”
Hash 确实能解决客户端体验问题,但它在 Next.js (SSR) 语境下有一个致命伤:
- 服务端看不见 Hash:请求发送到服务器时,
#后面的内容会被浏览器截断。服务器只知道你请求了/feed。 - SEO 和首屏体验差:爬虫抓不到弹窗内容;用户打开链接,必须等 JS 加载完读取 Hash 后,弹窗才会“闪”出来。
Parallel Routes 使用的是真实的 URL 路径。服务器知道你要看 /photo/123,可以直接生成包含弹窗内容的 HTML 返回给浏览器。首屏直出,SEO 友好。
总结:Layout vs Parallel Routes
如果把你的网页比作一间房子:
-
Layout (布局) 是承重墙和天花板。它定义了房子的结构,通常是不动的。
-
Parallel Routes (并行路由) 是房间里独立的家具区。
- 你可以一边换电视频道(路由 A 变动),一边在沙发上看书(路由 B 状态保留)。
- 你可以根据谁进来了(权限),决定是否把保险箱那个区域搬走(服务端条件渲染)。
一句话总结:
如果你的应用只是简单的页面跳转,普通 Layout 足矣;但如果你想构建一个状态丰富、多视图独立交互、且需要 URL 同步的 Web 应用(Web App),Parallel Routes 是 Next.js 提供的最佳架构方案。