Next Tradeoffs · Next.js 工程实践的选型对照站
把选型放到同一把尺子上
文档写能做什么。这里写该选哪条。 渲染光谱、RSC 边界、缓存、路由与 AI-Native,按专题展开成可运行的对照。
8 个领域 · 37 个专题
左静,右动。点一格,打开那一格的对照。五格放在一起看
学习顺序
从尺子走进目录
边界 → 渲染 → 路由 → 数据 → Metadata → 工程 → 安全 → AI
Server/Client 边界
RSC 优先;客户端 JS 是显式 opt-in
- RSC 心智模型为什么默认 Server:RSC 载荷是序列化的 UI 描述;每条 'use client' 边界都是一次 bundle 切点与序列化约束;Client 嵌 Server 走 children 槽
- Server/Client 边界page 保持 Server Component 预渲染,交互(搜索/添加)下沉到 Client Component;初始数据以 props 跨越边界
- Server Actions 留言板'use server' 变更 + <form action> 渐进增强:无 JS 也能提交;action 里 revalidatePath,列表随响应刷新
- 理解检验7 道问答,覆盖 "use client" 边界切点、children 槽、Flight 序列化约束、Server Actions 三件套与渐进增强。先用要点自答,再展开对照
渲染策略
SSG / ISR / SSR / Streaming / PPR 的光谱与选择
- 渲染光谱梳理SSG → ISR → SSR → Streaming → PPR 不是五个开关而是一条光谱:按首字节来源、数据新鲜度与服务器成本定位每格,按路由甚至按组件混用
- ISR 与静态再生"use cache" + cacheLife({ revalidate: 60 }) 的增量静态再生:产物预渲染并缓存,过期后后台重建;generateMetadata 与页面共享同一份缓存条目
- SSR 请求时整页渲染请求时渲染的内容:每次请求都在服务器现算完再补出。刷新本页,时刻和请求号都会变。只有内容必须实时时才落在这一格
- Streaming SSR 与 Suspense 粒度cacheComponents 下的真实流式渲染:静态壳构建期预渲染先行吐出,三个不同时延的异步区块作为动态洞各自包 Suspense 分段到达;边界粒度决定谁阻塞谁
- PPR 与 Cache Components本站已全站开启 cacheComponents:取数默认动态,"use cache" 显式标记静态部分;静态壳预渲染进 CDN,动态洞经 Suspense 流式补出 —— 本页即是活演示
- 页面转场 ViewTransitionReact 19.2 的 <ViewTransition> 经 Next 16 experimental.viewTransition 接进路由导航;本站顶栏与每个专题页已在真实使用方向感知转场 —— 本页把这条已实装的链路讲透
- 理解检验7 道问答,覆盖 SSG/ISR/SSR/Streaming/PPR 选型、cacheComponents 新模型、ISR 的 SWR 语义与构建输出路由表读法。先用要点自答,再展开对照
路由机制
文件系统路由、约定文件与导航缓存
- 动态路由与动态 metadata[id] 动态段保持 Server Component:generateStaticParams 预生成已知 id,generateMetadata 与页面同文件;不存在的 id 走 notFound()
- 约定文件对照page / layout / loading / error / not-found / template / default 各管什么:一张对照表 + 嵌套层级示意;本页自带真实 loading.tsx 演示 Suspense 边界
- 错误与未找到error.tsx 接渲染失败,not-found.tsx 接 notFound(),unauthorized/forbidden 接 401/403 认证中断;global-error.tsx 是根布局崩溃时换掉整个文档的最后一道
- 平行路由与拦截同一条 URL,两种渲染:从列表点进去是弹层(列表不卸载),刷新或硬导航是完整页。@modal 负责槽,(.)shot 负责拦截,default.tsx 保证直接打开列表时槽是空的
- 导航与 Router CacheLink 的 prefetch 默认行为、useRouter 的 push/replace/back/refresh,以及「为什么页面不刷新」的排查入口
- 路由组与多根布局(folder) 组织路由却不占 URL 段:组级 layout 按组圈定外壳,多根布局让营销站与应用壳在同一仓库共存;本页附带一个真实路由组活演示
- 国际化路由语言放进 URL 第一段:[lang] 动态段 + 字典模块 + generateStaticParams 预生成,非法语言走 notFound();再对照 middleware 重定向与子域名方案,划清「什么时候别自己拼」
数据与缓存
四层缓存心智模型与取数通道选择
- 四层缓存对照台Request Memoization / Data Cache / Full Route Cache / Router Cache:四层各管一段生命周期,「时新时不新」先定位是哪一层;四层名称出自旧模型,文末附 cacheComponents 演进备注
- 按需失效实战cacheTag 打标 + revalidateTag/updateTag 精准唤醒:SWR 与立即过期两种语义在同一份缓存产物上对照,tag 与 path 的失效粒度选择
- Route HandlerGET/POST/PUT/DELETE 四方法端点;Route Handler 与页面取数相互独立,各自直连外部服务避免构建期自调用
- 表单进阶:校验与错误回显zod 在 Server Action 里做权威校验:z.flattenError 拆出字段级错误回显到输入框下方;对照不设校验的 action 会收下什么
- 动态 API 各一格cookies / headers / connection / after 四个请求级 API 的活演示:前三个让所在格退出静态、必须待在 Suspense 洞内,after 在响应返回后收尾
- 客户端取数与 SWR客户端取数的正确打开方式:能在 Server Component 里 await 就别用 SWR;但会话数据、聚焦重验证、轮询、离线缓存仍是 SWR 的主场
- 理解检验7 道问答,覆盖四层缓存与模型演进、四个失效/刷新 API 的分工、zod 校验位置、动态 API 与 Suspense 洞、SWR 适用边界。先用要点自答,再展开对照
Metadata 与 SEO
metadata 流水线:静态导出、动态生成与约定文件
工程化
中间件边界、缓存策略设计与资产性能治理
- Proxy 与中间件Next 16 的 proxy.ts 固定跑在 Node;本站仍用 middleware.ts 做边缘改头演示,页面能读到同一枚请求头。matcher 之外的路由不会经过它
- 缓存策略设计给一个页面定缓存方案的决策流程:数据归属 → 新鲜度要求 → 变更触发方式,落到 cacheLife / cacheTag / revalidateTag / 默认动态
- Image/Font 与包体治理next/image 的尺寸/懒加载/格式协商、next/font 的自托管零 CLS,以及动态 import 与客户端边界下沉的包体治理
- 构建、测量与部署Turbopack 已是 Next 16 默认打包器;@next/bundle-analyzer 以 --webpack 回退实装(pnpm analyze 可跑,报告在 .next/analyze/);部署侧讲 standalone 自托管、instrumentation + OTel 与 after()
安全
安全响应头与 CSP、Server/Client 信任边界
AI-Native 与 Agent
流式端点、Generative UI 与长任务体验
- AI 流式响应真实 SSE 流式端点:Route Handler 用 ReadableStream 逐 token 推送,前端 getReader() 边收边渲染;TTFT 才是用户感知的「快」,取消即省计费
- Generative UI模型输出结构化工具调用,UI 层做组件映射:天气卡片、股价走势图、待办清单直接渲染成真实 React 组件,与文本气泡混排在同一条消息流
- Agent 长任务页多步 Agent 任务流的过程可视化:SSE 推送步骤事件,前端渲染 pending/running/done 时间线;串行 vs 并行墙钟对照,取消即省计费
- 手写 SSE vs Vercel AI SDK同一个聊天场景做两遍:手写 ReadableStream + getReader() 对照 streamText + useChat;SDK 收编了分帧、取消与协议演进,还带来多 provider、tool calling 与 data parts