我用五层架构重建了整个 Next.js 项目,从污染地狱爬上了性能天堂

"我们不只是开发功能,更在搭建一座长期可演化的工程大厦。"

在 React Server Components(RSC) 和 Next.js App Router 成为主流架构范式的今天,许多开发者仍在"性能"和"结构混乱"之间痛苦拉扯。本文将分享我在真实项目中不断试验、打磨,最终沉淀下来的架构设计方法------RSC 优先的五层架构模型(5-Layer Architecture)

它不仅提升了性能,更彻底解决了可维护性和可控性问题。


❌ 默认目录结构的问题

很多基于 Next.js 构建的项目会逐步陷入以下困境:

  • Client 组件向上传染,污染了原本能 SSR 的组件
  • 过度依赖 index.ts 导致依赖边界不清晰
  • 首屏加载变慢,LCP 高、TBT 爆炸、JS 包臃肿
  • 小改动带来系统性结构崩溃,维护代价极高

经过多轮战斗之后,我终于明白:

架构应该服务于团队的长期演进,而不是阻碍它。

于是我彻底推翻原有结构,从零构建了一套新模型。


🧱 五层架构模型简介

sql 复制代码
RootLayout → Page Layout → Page → View → Component

每一层都有严格的职责边界,并明确规定了哪些层可以使用 Client Component(CSC)。

层级 职责说明 是否允许 CSC 是否允许改动
RootLayout 顶层布局:定义 <html>、全局 Provider、样式等 ❌ 禁止 ❌ 冻结不可改
Page Layout 路由级布局:如主框架导航栏、布局结构 ❌ 禁止 ❌ 冻结不可改
Page 页面入口:生成 Metadata,调用唯一 View ❌ 禁止 ❌ 冻结不可改
View 视图层:组合多个组件构成完整页面 ❌ 禁止直接 CSC ✅ 可随时调整
Component 原子组件:具备 UI 行为逻辑,可含 useState/useEffect ✅ 允许 ✅ 可随时修改

✅ 架构执行规则(必须遵守)

1️⃣ 只有 Component 层可以使用 use client

绝不允许 View/Page/Layout 层直接使用 use client,只允许在组件中声明。

typescript 复制代码
// ✅ 合法写法,仅在组件内使用
'use client';
export function Chart() {
  ...
}
typescript 复制代码
// ❌ 非法写法,污染上层结构
'use client';
export function DashboardView() {
  ...
}

2️⃣ 所有 CSC 都必须 Lazy 加载

所有 CSC 组件都必须通过 next/dynamic + ssr: false 实现懒加载,并强制执行统一命名规范:

typescript 复制代码
// ✅ 推荐方式
import { ChartLazy } from '@/components/csc/chart-lazy';

// ❌ 禁止方式
import { Chart } from '@/components/csc/chart';

📂 所有 CSC 组件统一放在 components/csc/ 目录下,并以 xxx-lazy.tsx 命名。


3️⃣ 每个 Page 只返回一个 View

页面只负责生成 SEO Metadata 和调用 View。内容结构全部交给 View 层负责拼装:

typescript 复制代码
export default async function Page() {
  return <ImageResizeView />;
}

4️⃣ View 层必须保持纯 RSC,不可被污染

View 层可以使用 Lazy 的 CSC 组件,但绝不允许直接引入 CSC。

typescript 复制代码
// ✅ 允许:View 使用 Lazy 组件
import { CompressChartLazy } from '@/components/csc/compress-chart-lazy';

// ❌ 禁止:直接引入 CSC 会污染 View
import { CompressChart } from '@/components/csc/compress-chart';

这是保障 RSC 流、缓存可用、HTML 可预生成的关键。


📁 目录结构示例

采用DDD范式驱动的目录分层结构

bash 复制代码
/src
  ├── app
  │   ├── layout.tsx                  # RootLayout
  │   └── [locale]
  │       ├── layout.tsx              # Page Layout
  │       └── tools
  │           └── image-compress
  │               └── page.tsx       # Page

  ├── features
  │   └── image-compress
  │       └── image-compress-view.tsx  # View

  └── components
      ├── ui/
      └── csc/
          └── compress-chart-lazy.tsx   # Client Component(CSC)

🚀 实际收益提升

这套架构在我主导的 Toolbox 项目中已经应用于数十个工具页面,收获如下:

指标 优化前 → 优化后
Lighthouse 分数 提升 15--30 分
TBT 降至 100ms 以下
首屏 JS(FLJ) 缩减 300KB+
LCP 控制在 2.5s 内
团队协作 职责边界清晰,写代码不迷路

next build 全部页面 FLJ大幅降低,页面需要处理的JS少了,自然也就快了!


🧠 写在最后

这套五层架构模型,适用于一切追求:

  • ✅ 高性能
  • ✅ 可维护性
  • ✅ RSC-first
  • ✅ SEO优化

的中大型 Next.js 项目。

它并不是一套通用的"套路",而是一种严肃、稳定、可验证的架构哲学

你需要做的,就是把复杂度往下沉,把污染挡在边界之外。


👨‍💻 作者:AiMuo / Toolbox 项目

📎 项目地址:aimuo.com

📌 更多工程实践持续分享中,欢迎关注!

相关推荐
名字还没想好☜9 小时前
Next.js Route Handler 做 SSE 服务端推送:实时进度条、自动重连与什么时候别用 WebSocket
开发语言·javascript·websocket·react·sse·next.js
To_OC2 天前
Next.js + Redis 构建笔记系统:Redis Hash 实战与性能优化
redis·后端·next.js
山海入梦2 天前
Windows 上 Next.js `standalone` + pnpm:「构建成功却把 next 删空」的踩坑记录
next.js
HjhIron3 天前
手把手教你用 Next.js 14 + Redis 从零搭建一个全栈 Markdown 笔记系统
前端·全栈·next.js
To_OC4 天前
写了三天 Next.js,我的 React 世界观被拆了又装回去
前端·全栈·next.js
名字还没想好☜4 天前
Next.js 用 Server Components 直连数据库:去掉 API 层的边界,和三条别踩的安全红线
前端·javascript·数据库·安全·react·next.js
不知疲倦的老鸟4 天前
Next.js 15 多语言站点的 6 个坑:从 query string 路由到 URL 路径
typescript·next.js
JieE2124 天前
Next.js App Router 全栈实战:从零构建一个 Markdown 笔记系统
全栈·next.js
DsirNg4 天前
React Server Components 在真实项目中的边界:哪些组件该放在服务端
性能优化·react·next.js·app router·前端架构·rsc·react server components
Asize5 天前
为什么写代码前要先规划组件树?Next.js + Redis 笔记系统实战
前端·javascript·next.js