Next.js 落地指南 / 01 / Parallel Routes 篇

5 阅读4分钟

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 下同时渲染两层内容:

  1. @children:继续渲染首页(作为背景)。
  2. @modal:渲染照片弹窗(覆盖在上面)。

这让你既拥有了 SPA 的体验(不刷新、保留上下文),又拥有了 MPA 的能力(URL 变了,可以直接复制分享链接)。


3. 服务端视角的“条件渲染” (Server-Side Conditional UI)

场景:一个页面,根据用户角色(Admin vs User)显示不同的板块。

❌ 传统组件写法

你可能会在组件里写大量的 if (isAdmin) return <AdminPanel />

  • 隐患:即使不渲染,组件代码可能依然被打包到了客户端 Bundle 中。且逻辑耦合在组件内部,不易维护。

✅ Parallel Routes 的解法

利用 layout.jsdefault.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 提供的最佳架构方案。