Nuxt 3 代表了 Vue 生态中全栈框架的最高水准。其全新的 Nitro 引擎统一了服务端和构建时的渲染逻辑,让 SSR、SSG、ISR 的切换变得前所未有地简单。
三种渲染模式的本质差异
理解 Nitro 的工作机制,首先需要明确三种渲染模式在请求生命周期上的不同:
<script setup lang="ts">
import { useAsyncData, useFetch, definePageMeta } from '#app'
definePageMeta({
name: 'products-id',
path: '/products/:id',
middleware: ['auth'],
layout: 'shop'
})
const route = useRoute()
const { data: product, pending, refresh, error } = await useAsyncData(
`product-${route.params.id}`,
() => $fetch(`/api/products/${route.params.id}`),
{
server: true,
lazy: false,
default: () => ({}),
transform: (res) => ({
...res,
formattedPrice: new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(res.price)
})
}
)
const { data: related } = await useFetch(
'/api/products/related',
{
params: { id: route.params.id, limit: 4 },
pick: ['items']
}
)
useHead({
title: () => product.value?.name,
meta: [
{ name: 'description', content: () => product.value?.description }
]
})
const isrTimestamp = ref(Date.now())
</script>
<template>
<div class="product-page">
<Suspense>
<template #default>
<ProductDetail v-if="product" :product="product" />
<div v-else-if="error" class="error">{{ error.message }}</div>
</template>
<template #fallback>
<ProductSkeleton />
</template>
</Suspense>
<RelatedProducts v-if="related" :items="related.items" />
</div>
</template>
性能与成本对比
| 渲染模式 | 首屏 TTFB | 可交互时间 TTI | 服务器成本 | SEO 友好 | 适用场景 |
|---|---|---|---|---|---|
| SSR | ⚡ 300-600ms | ✅ 优秀 | 💸 高 | ✅ 最佳 | 个性化、实时数据 |
| SSG | ⚡⚡⚡ <50ms | ✅ 最佳 | 🆓 极低 | ✅ 最佳 | 文档、博客、产品页 |
| ISR | ⚡⚡ <100ms* | ✅ 优秀 | 💰 中 | ✅ 良好 | 电商、新闻、中低频更新 |
| CSR (SPA) | 🐢 200ms + JS | ❌ 较差 | 🆓 极低 | ⚠️ 需额外处理 | Dashboard、后台管理 |
*首次访问后命中缓存的情况
缓存策略配置
Nitro 提供了多层缓存机制。对于 SSR 页面,可以通过 routeRules 配置 CDN 级缓存:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/products/**': { swr: 3600 },
'/api/**': { swr: 60, cache: { maxItems: 1000 } },
'/static/**': { static: true }
}
})
SWR(Stale-While-Revalidate)模式让用户在后台刷新数据的同时立即返回缓存响应,兼顾了性能和数据新鲜度。
水合优化技巧
SSR 模式下,客户端需要对服务端渲染的 HTML 进行水合(Hydration)。常见的性能陷阱包括:
- Payload 过大:使用
definePageMeta的payloadExtractor精简传递给客户端的数据 - 过早水合:使用
<ClientOnly>包裹非首屏必须的交互组件 - 重复请求:合理设置 useAsyncData 的 key,利用 Nitro 自动的数据去重
最佳实践
- 默认用 SSG,除非页面强依赖实时或个性化数据
- 组合渲染模式:首页 SSG + 详情页 ISR + 用户中心 SSR,而不是一刀切
- 善用 Nitro API Routes,避免单独部署后端服务(对于中小项目)
- 监控 TTFB 分布,如果 P95 > 1s,考虑开启缓存或切换 ISR
- 使用
nuxt build --prerender预渲染高频页面,降低冷启动耗时
总结
Nuxt 3 的 Nitro 引擎彻底抹平了 SSR 与 SSG 的开发差异。开发者只需关注业务逻辑,通过配置文件即可在不同渲染模式间切换。选择渲染模式的关键在于:页面更新频率 × 内容个性化程度 × 团队运维能力。