Next.js 15 将 Server Components 和 Server Actions 纳入稳定功能,Turbopack Dev 也达到生产可用状态,并重构了缓存策略。本文梳理 2025 年 Next.js 15 App Router 的核心最佳实践。
一、Server Components 优先策略
app/ 目录下的组件默认都是服务端组件,基本原则是:尽量让父组件(页面)是服务端组件负责取数据,把数据作为 props 传给客户端组件负责交互。
// ✅ 推荐:Server Component 直接获取数据
export default async function Page() {
const data = await fetch('https://api.example.com/data');
const json = await data.json();
return <div>{json.title}</div>;
}
// ❌ 避免:不必要的 Client Component
'use client';
export default function Page() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/data').then(r => r.json()).then(setData);
}, []);
return <div>{data?.title}</div>;
}二、数据获取策略
Next.js 对原生 fetch 做了扩展,支持缓存控制:
// ISR 模式:每 24 小时重新验证
fetch(url, { next: { revalidate: 86400 } });
// SSR 模式:每次请求都重新获取
fetch(url, { cache: 'no-store' });
// SSG 模式:永久缓存
fetch(url, { cache: 'force-cache' });在 Server Component 中推荐使用原生 fetch 而非 axios,因为只有原生 fetch 能享受 Next.js 的缓存扩展能力。axios 在客户端组件中完全可用。
三、路由系统要点
文件即路由:
app/page.tsx→/app/about/page.tsx→/aboutapp/posts/[id]/page.tsx→/posts/:id(动态路由)app/blog/[...slug]/page.tsx→/blog/*(捕获所有路由)
Next.js 15 重要变更:params 现在是 Promise 类型,需要使用 await:
export default async function PostPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
// ...
}四、缓存策略重构
Next.js 15 将缓存从"隐式默认"改为"显式可控":
- GET 路由处理程序默认不再缓存
- 客户端路由缓存默认不再缓存页面组件
- 开发者需要显式声明缓存策略
这一变更使行为更加可预测,但也要求开发者明确思考每个请求的缓存需求。
五、路由守卫实现
在项目根目录创建 middleware.ts:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
}六、并行数据获取
利用 Promise.all 避免瀑布式请求:
const [user, posts, comments] = await Promise.all([
getUser(params.id),
getPosts(params.id),
getComments(params.id),
]);
评论