数据获取时间:2025-12-17T09:54:11.734Z
数据获取耗时:2001ms
Layout 总耗时:2001ms
在 Next.js App Router 中,layout 和 page 的数据获取是并行的, 而不是串行等待。这意味着如果 layout 需要 2 秒,page 需要 3 秒, 总渲染时间接近 3 秒(取最长的),而不是 5 秒(2 + 3)。
本次测试配置:
数据获取时间:2025-12-17T09:54:12.735Z
数据获取耗时:3001ms
Page 总耗时:3001ms
⚡ 节省时间:5秒 - 3秒 = 2秒(40% 性能提升)
刷新页面后,观察终端输出:
• [LAYOUT] 开始获取数据
• [PAGE] 开始获取数据
这两个日志的时间戳几乎相同 → 证明是并行启动
- Layout 完成:约 2000ms
- Page 完成:约 3000ms
- 总渲染时间:约 3000ms(而不是 5000ms)
打开 Network 面板,刷新页面:
• 等待约 3 秒后,页面一次性显示(包括 Layout 和 Page)
• 如果是串行,需要等待 5 秒
计算 [LAYOUT] 开始 和 [PAGE] 开始 的时间差
→ 时间差接近 0ms = 并行 ✅
→ 时间差接近 2000ms = 串行 ❌
Next.js App Router 基于 React 18 的并发渲染能力, 可以同时启动多个异步操作,而不需要等待前一个完成。
当 Next.js 开始渲染一个路由时,会:
如果有多层嵌套的 layout,它们的数据获取也会并行进行:
app/layout.tsx (1秒) ┐ app/dashboard/layout.tsx (2秒) ├─ 并行 app/dashboard/page.tsx (3秒) ┘ 总耗时 ≈ 3秒(而不是 6秒)
// app/dashboard/layout.tsx
export default async function DashboardLayout({ children }) {
// Layout 数据获取(例如:用户信息)
const user = await fetchUser(); // 1秒
return (
<div>
<nav>Welcome, {user.name}</nav>
{children}
</div>
);
}
// app/dashboard/page.tsx
export default async function DashboardPage() {
// Page 数据获取(例如:仪表盘数据)
const stats = await fetchStats(); // 2秒
return <div>Stats: {stats.total}</div>;
}
// 渲染流程:
// 0ms: 同时启动 fetchUser() 和 fetchStats()
// 1000ms: fetchUser() 完成
// 2000ms: fetchStats() 完成 → 页面渲染完成
// 总耗时:2秒(而不是 3秒)✅页面会等待最慢的那个完成
但同级的 layout 和 page 是并行的
建议在生产环境(pnpm build && pnpm start)测试