Nuxt 4服务端渲染性能优化实战指南

Nuxt 4 SSR优化概览 Nuxt 4基于Vue 3和Nitro构建,提供了强大的SSR能力。本文将深入分析各种性能优化技术。 服务端缓存策略 routeRules缓存 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // nuxt.config.ts export default defineNuxtConfig({ routeRules: { // 静态页面缓存1小时 '/': { isr: 3600 }, // API缓存 '/api/**': { cors: true, headers: { 'cache-control': 'max-age=60' } }, // 动态路由ISR '/blog/**': { isr: true }, // 完全静态 '/about': { isr: false }, // SPA模式 '/app/**': { ssr: false } } }) 服务端数据缓存 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // server/api/data.ts export default defineEventHandler(async (event) => { // 使用Nitro存储缓存 const storage = useStorage('redis') const cached = await storage.getItem('expensive-data') if (cached) { return cached } const data = await fetchExpensiveData() await storage.setItem('expensive-data', data, { ttl: 3600 }) return data }) useAsyncData缓存 1 2 3 4 5 6 7 8 9 10 11 12 13 <script setup lang="ts"> // 缓存API响应 const { data, refresh } = await useAsyncData( 'user-profile', () => $fetch('/api/user/profile'), { transform: (data) => data.result, // 5分钟缓存 getCachedData: (key) => useNuxtData(key).data, dedupe: 'cancel' } ) </script> 流式渲染 使用Suspense流式渲染 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!-- app.vue --> <template> <div> <NuxtPage /> </div> </template> <!-- pages/index.vue --> <template> <div> <!-- 立即渲染部分 --> <header>Header</header> <!-- 异步组件流式加载 --> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <LoadingSkeleton /> </template> </Suspense> <footer>Footer</footer> </div> </template> Nitro流式响应 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // server/api/stream.ts export default defineEventHandler(async (event) => { const stream = new ReadableStream({ async start(controller) { for (let i = 0; i < 10; i++) { const data = `chunk ${i}\n` controller.enqueue(new TextEncoder().encode(data)) await new Promise(resolve => setTimeout(resolve, 100)) } controller.close() } }) return sendStream(event, stream) }) Hydration优化 懒加载Hydration 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <template> <div> <!-- 关键内容立即hydration --> <CriticalContent /> <!-- 非关键内容延迟hydration --> <LazyNonCritical @vue:mounted="hydrateComponent" /> </div> </template> <script setup> function hydrateComponent() { // 组件mounted后才hydration } </script> 选择性Hydration 1 2 3 4 5 6 7 8 9 10 <script setup> // 只hydration需要的部分 const { data } = await useAsyncData('posts', () => $fetch('/api/posts'), { // 只在客户端获取 server: false } ) </script> 性能监控 服务端性能追踪 1 2 3 4 5 6 7 8 9 // server/middleware/performance.ts export default defineEventHandler((event) => { const start = Date.now() event.node.res.on('finish', () => { const duration = Date.now() - start console.log(`[Performance] ${event.node.req.url} - ${duration}ms`) }) }) 使用Nitro钩子 1 2 3 4 5 6 7 // server/plugins/performance.ts export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook('renderResponse', (response, { event }) => { const timing = Date.now() - event.context.startTime event.node.res.setHeader('X-Response-Time', `${timing}ms`) }) }) 数据获取优化 并行数据获取 1 2 3 4 5 6 7 8 <script setup lang="ts"> // 并行获取多个数据 const [user, posts, comments] = await Promise.all([ $fetch('/api/user'), $fetch('/api/posts'), $fetch('/api/comments') ]) </script> useLazyAsyncData延迟加载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <script setup lang="ts"> // 不阻塞导航 const { data, pending } = useLazyAsyncData( 'dashboard', () => $fetch('/api/dashboard') ) </script> <template> <div> <h1>Dashboard</h1> <div v-if="pending">Loading...</div> <div v-else>{{ data }}</div> </div> </template> 预渲染策略 静态生成 1 2 3 4 5 # 生成静态站点 nuxt generate # 仅预渲染特定路由 nuxt generate --prerender /about /contact 增量静态再生 1 2 3 4 5 6 7 8 9 10 11 // nuxt.config.ts export default defineNuxtConfig({ routeRules: { '/blog/**': { // ISR:每小时重新生成 isr: 3600, // 允许预渲染 prerender: true } } }) 代码分割优化 动态导入 1 2 3 4 5 6 7 8 9 10 11 12 <script setup> // 组件懒加载 const HeavyComponent = defineAsyncComponent(() => import('~/components/HeavyComponent.vue') ) </script> <template> <Suspense> <component :is="HeavyComponent" /> </Suspense> </template> 路由级代码分割 1 2 3 4 5 6 7 // nuxt.config.ts export default defineNuxtConfig({ experimental: { // 启用路由级代码分割 typedPages: true } }) 生产环境优化 构建优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // nuxt.config.ts export default defineNuxtConfig({ vite: { build: { // Rollup配置 rollupOptions: { output: { // 手动代码分割 manualChunks: { 'vue-vendor': ['vue', 'vue-router', '@vue/runtime-core'], 'ui-vendor': ['@headlessui/vue', 'heroicons'] } } } } }, // 压缩 nitro: { minify: true } }) CDN配置 1 2 3 4 5 6 7 8 9 10 11 // nuxt.config.ts export default defineNuxtConfig({ app: { // 静态资源CDN cdnURL: 'https://cdn.example.com' }, // 压缩中间件 nitro: { compressPublicAssets: true } }) 总结 Nuxt 4提供了完整的SSR优化工具链。通过合理使用缓存、流式渲染、Hydration优化等技术,可以显著提升应用性能。 ...

2025年Next.js 15 App Router实战指南:从零构建现代化Web应用

前言 Next.js 15 带来了许多令人兴奋的新特性,特别是 App Router 的成熟和稳定。相比传统的 Pages Router,App Router 提供了更强大的路由控制、更好的性能优化和更直观的文件组织方式。 本文将带您从零开始,使用 Next.js 15 App Router 构建一个完整的现代化 Web 应用,深入探讨每个核心概念和实战技巧。 一、App Router 核心概念 1.1 App Router vs Pages Router 特性 Pages Router (传统) App Router (新) 文件位置 pages/ 目录 app/ 目录 路由方式 文件系统路由 文件系统路由 数据获取 getServerSideProps 服务器组件 + fetch 布局 需要 _app.js 内置 Layout 系统 加载状态 手动实现 自动 loading.js 错误处理 _error.js error.js 流式渲染 不支持 支持 服务器组件 不支持 原生支持 1.2 文件组织结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 my-app/ ├── app/ │ ├── (marketing)/ # 路由组 - 不影响URL │ │ ├── about/ │ │ │ └── page.js # /about │ │ ├── layout.js # 共享布局 │ │ └── page.js # / (首页) │ ├── (dashboard)/ # 路由组 │ │ ├── dashboard/ │ │ │ ├── layout.js # Dashboard布局 │ │ │ ├── page.js # /dashboard │ │ │ └── settings/ │ │ │ └── page.js # /dashboard/settings │ │ └── layout.js # 认证布局 │ ├── api/ # API路由 │ │ └── users/ │ │ └── route.js # /api/users │ ├── layout.js # 根布局 │ ├── page.js # 根页面 │ ├── loading.js # 全局加载状态 │ ├── error.js # 全局错误处理 │ ├── not-found.js # 404页面 │ └── globals.css # 全局样式 ├── public/ # 静态资源 ├── components/ # 共享组件 ├── lib/ # 工具函数 └── next.config.js # Next.js配置 二、路由系统实战 2.1 动态路由 基础动态路由 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // app/blog/[slug]/page.tsx interface BlogPostProps { params: { slug: string } } export default async function BlogPost({ params }: BlogPostProps) { const { slug } = params // 在服务器端获取数据 const post = await fetch(`https://api.example.com/posts/${slug}`) .then(res => res.json()) return ( <article> <h1>{post.title}</h1> <p>{post.content}</p> </article> ) } 捕获所有路由 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // app/docs/[...slug]/page.tsx // 匹配 /docs/a, /docs/a/b, /docs/a/b/c 等 export default async function DocPage({ params }: { params: { slug: string[] } }) { const path = params.slug.join('/') const content = await fetch(`https://api.example.com/docs/${path}`) .then(res => res.json()) return ( <div> <h1>文档: {path}</h1> <div>{content.body}</div> </div> ) } 2.2 路由组(Route Groups) 路由组允许您组织文件结构而不影响 URL 路径: ...

Next.js 15服务端组件深度解析:从React Server Components到全栈开发的范式转移

前言 React Server Components (RSC) 是 React 团队在 2020 年底引入的革命性特性,Next.js 15 将这一特性推向了成熟。RSC 不仅仅是渲染方式的改变,更是前端开发范式的一次重大转移。 本文将从实现原理的角度,深入解析 Next.js 15 中 React Server Components 的工作机制,帮助您真正理解这一技术背后的设计哲学和最佳实践。 一、RSC 的核心概念 1.1 什么是 Server Components Server Components 是一种特殊的 React 组件,它们: 在服务器上渲染:完全不发送 JavaScript 到客户端 直接访问后端资源:可以读取数据库、文件系统、内部 API 不包含交互性:不能使用 hooks (useState, useEffect) 和事件处理器 流式传输:支持渐进式渲染,可以逐步发送 UI 片段 1.2 客户端组件 vs 服务端组件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // ✅ Server Component (默认) // 文件名: app/components/UserList.tsx import { db } from '@/lib/db' export default async function UserList() { // 可以直接访问数据库 const users = await db.user.findMany() return ( <div> {users.map(user => ( <div key={user.id}>{user.name}</div> ))} </div> ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // ✅ Client Component // 文件名: app/components/UserCard.tsx 'use client' import { useState } from 'react' export function UserCard({ userId }: { userId: string }) { // 可以使用 hooks const [liked, setLiked] = useState(false) return ( <div> <button onClick={() => setLiked(!liked)}> {liked ? '❤️' : '🤍'} </button> </div> ) } 1.3 架构对比 传统 React 架构 ┌─────────────────────────────────────────┐ │ Browser (Client) │ │ ┌───────────────────────────────────┐ │ │ │ React App (JavaScript Bundle) │ │ │ │ ├── Components │ │ │ │ ├── State Management │ │ │ │ └── API Calls (fetch) │ │ │ └───────────────────────────────────┘ │ └─────────────────────────────────────────┘ ↕ HTTP Request ┌─────────────────────────────────────────┐ │ Server (API) │ │ ┌───────────────────────────────────┐ │ │ │ Database │ │ │ │ File System │ │ │ │ Internal Services │ │ │ └───────────────────────────────────┘ │ └─────────────────────────────────────────┘ RSC 架构 ┌─────────────────────────────────────────┐ │ Browser (Client) │ │ ┌───────────────────────────────────┐ │ │ │ Client Components (Interactive) │ │ │ │ ├── Event Handlers │ │ │ │ ├── State (useState) │ │ │ │ └── Effects (useEffect) │ │ │ └───────────────────────────────────┘ │ │ ↕ (RSC Payload - JSON) │ │ ┌───────────────────────────────────┐ │ │ │ React Server Runtime │ │ │ │ (Reconstructs Server Tree) │ │ │ └───────────────────────────────────┘ │ └─────────────────────────────────────────┘ ↕ HTTP Request ┌─────────────────────────────────────────┐ │ Server │ │ ┌───────────────────────────────────┐ │ │ │ Server Components │ │ │ │ ├── Direct DB Access │ │ │ │ ├── File System Access │ │ │ │ └── Internal APIs │ │ │ └───────────────────────────────────┘ │ └─────────────────────────────────────────┘ 二、RSC 渲染流程 2.1 完整渲染周期 1. Request ↓ 2. Server renders Server Components to RSC Payload ↓ 3. Server sends HTML + RSC Payload to Client ↓ 4. Browser displays HTML (immediate paint) ↓ 5. React hydrates Client Components ↓ 6. React reconstructs Server Tree from RSC Payload ↓ 7. Interactive 2.2 RSC Payload 格式 RSC Payload 是一种特殊的 JSON 格式,用于描述组件树: ...