nuxt
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNuxt Best Practices
Nuxt最佳实践
Guidance for building high-performance Nuxt 4 applications following official best practices. Covers rendering strategies, performance optimization, data fetching, component patterns, and profiling.
本指南介绍如何遵循官方最佳实践构建高性能Nuxt 4应用,内容涵盖渲染策略、性能优化、数据获取、组件模式以及性能分析。
Rendering Strategies
渲染策略
Choose the Right Rendering Mode per Route
为每个路由选择合适的渲染模式
Nuxt 4 supports hybrid rendering via . Assign rendering strategies per route rather than using a single global mode:
routeRulests
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // Static at build time
'/products/**': { swr: 3600 }, // Cached, revalidated in background
'/blog': { isr: 3600 }, // CDN-cached, revalidated hourly
'/admin/**': { ssr: false }, // Client-side only
'/api/**': { cors: true },
},
})Route rule reference:
- — generate at build time, serve as static asset
prerender: true - — server/proxy cache for N seconds, stale-while-revalidate
swr: N - — CDN cache until next deploy (Vercel/Netlify);
isr: Nmeans persist indefinitelyisr: true - — browser-only rendering (SPA mode for that route)
ssr: false - — server-side redirect
redirect: '/new' - — add custom response headers (e.g., long cache on assets)
headers: {}
Nuxt 4通过支持混合渲染。可为每个路由分配单独的渲染策略,而非使用单一全局模式:
routeRulests
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // 构建时生成静态资源
'/products/**': { swr: 3600 }, // 缓存,后台自动重新验证
'/blog': { isr: 3600 }, // CDN缓存,每小时重新验证
'/admin/**': { ssr: false }, // 仅客户端渲染
'/api/**': { cors: true },
},
})路由规则参考:
- — 构建时生成,作为静态资源提供
prerender: true - — 服务器/代理缓存N秒,采用stale-while-revalidate策略
swr: N - — CDN缓存至下次部署(Vercel/Netlify);
isr: N表示永久缓存isr: true - — 仅浏览器端渲染(该路由采用SPA模式)
ssr: false - — 服务端重定向
redirect: '/new' - — 添加自定义响应头(例如,为资源设置长缓存时间)
headers: {}
Default to Universal Rendering
默认使用Universal渲染
Universal rendering (SSR + hydration) is the default and best choice for content-oriented apps (blogs, e-commerce, marketing sites). It delivers:
- Immediate HTML visible to users and crawlers
- Full interactivity after hydration
- Better Core Web Vitals scores (LCP, CLS)
Universal渲染(SSR + 水合)是默认且最适合内容型应用(博客、电商、营销网站)的选择。它能提供:
- 用户和爬虫可立即看到HTML内容
- 水合完成后实现完整交互性
- 更优的Core Web Vitals评分(LCP、CLS)
Edge-Side Rendering
边缘端渲染
Deploy to CDN edge servers (Cloudflare Workers, Vercel Edge, Netlify Edge) for reduced latency. Nuxt's Nitro engine supports these out of the box — no code changes required, only a different build preset.
See for a full breakdown of trade-offs and deployment targets.
references/rendering.md部署到CDN边缘服务器(Cloudflare Workers、Vercel Edge、Netlify Edge)以降低延迟。Nuxt的Nitro引擎原生支持这些环境——无需修改代码,仅需选择不同的构建预设即可。
详细的权衡分析和部署目标可查看。
references/rendering.mdComponent Best Practices
组件最佳实践
Lazy-Load Non-Critical Components
懒加载非核心组件
Prefix any component with to defer its JavaScript until needed. This directly reduces initial bundle size and improves Time to Interactive (TTI):
Lazyhtml
<script setup lang="ts">
const show = ref(false)
</script>
<template>
<div>
<button @click="show = true">Load list</button>
<LazyMountainsList v-if="show" />
</div>
</template>为任意组件添加前缀,可延迟其JavaScript加载至需要时。这能直接减小初始包体积,提升交互时间(TTI):
Lazyhtml
<script setup lang="ts">
const show = ref(false)
</script>
<template>
<div>
<button @click="show = true">加载列表</button>
<LazyMountainsList v-if="show" />
</div>
</template>Use Lazy Hydration (Nuxt 3.16+)
使用懒水合(Nuxt 3.16+)
Defer hydration of components until they enter the viewport or the browser is idle. This improves TTI without sacrificing SSR-rendered content:
html
<template>
<!-- Hydrate only when scrolled into view -->
<LazyCommentSection hydrate-on-visible />
<!-- Hydrate when browser is idle -->
<LazyAnalyticsWidget hydrate-on-idle />
<!-- Hydrate on user interaction -->
<LazyChatWidget hydrate-on-interaction />
</template>延迟组件水合,直到其进入视口或浏览器空闲时再执行。这能在不牺牲SSR渲染内容的前提下提升TTI:
html
<template>
<!-- 进入视口时再水合 -->
<LazyCommentSection hydrate-on-visible />
<!-- 浏览器空闲时水合 -->
<LazyAnalyticsWidget hydrate-on-idle />
<!-- 用户交互时水合 -->
<LazyChatWidget hydrate-on-interaction />
</template>Avoid Overusing Plugins
避免过度使用插件
Plugins execute during the hydration phase and block interactivity. Audit plugins regularly — if logic does not need to run globally at startup, move it to a composable or utility function instead.
插件会在水合阶段执行,阻碍交互性。定期审核插件——如果逻辑无需在启动时全局运行,可将其移至composable或工具函数中。
Data Fetching
数据获取
Use useFetch
and useAsyncData
useFetchuseAsyncData使用useFetch
和useAsyncData
useFetchuseAsyncDataThese composables deduplicate server-side fetches. Data fetched on the server is serialized into the page payload and reused by the client — no double fetch:
ts
// Good: data transferred via payload, no duplicate network request
const { data } = await useFetch('/api/products')
// Bad: runs separately on server and client
const data = await $fetch('/api/products')这些composable可避免服务端请求重复。在服务端获取的数据会被序列化到页面负载中,供客户端复用——不会出现重复请求:
ts
// 推荐:数据通过负载传输,无重复网络请求
const { data } = await useFetch('/api/products')
// 不推荐:在服务端和客户端分别执行
const data = await $fetch('/api/products')Keep Composables Synchronous at the Top Level
在顶层保持Composable同步调用
Vue and Nuxt composables rely on a synchronous lifecycle context. Do not call composables after an outside of , , , or :
await<script setup>defineNuxtComponentdefineNuxtPlugindefineNuxtRouteMiddlewarets
// Bad
const data = await someAsyncOperation()
const config = useRuntimeConfig() // context lost
// Good — call composable before await, or inside <script setup>
const config = useRuntimeConfig()
const data = await someAsyncOperation()Vue和Nuxt的composable依赖同步的生命周期上下文。请勿在、、或之外的之后调用composable:
<script setup>defineNuxtComponentdefineNuxtPlugindefineNuxtRouteMiddlewareawaitts
// 不推荐
const data = await someAsyncOperation()
const config = useRuntimeConfig() // 上下文已丢失
// 推荐——在await之前调用composable,或在<script setup>内部调用
const config = useRuntimeConfig()
const data = await someAsyncOperation()Performance Optimization
性能优化
Images: Use <NuxtImg>
<NuxtImg>图片:使用<NuxtImg>
<NuxtImg>Replace all tags with (requires ). It auto-converts to WebP/Avif, resizes, and generates responsive :
<img><NuxtImg>@nuxt/imagesizeshtml
<!-- Above-the-fold / LCP image -->
<NuxtImg
src="/hero.jpg"
format="webp"
preload
loading="eager"
fetch-priority="high"
width="1200"
height="600"
/>
<!-- Below-the-fold image -->
<NuxtImg
src="/feature.jpg"
format="webp"
loading="lazy"
fetch-priority="low"
width="600"
height="400"
/>Always set and to prevent layout shift (CLS).
widthheight将所有标签替换为(需安装)。它会自动转换为WebP/Avif格式、调整尺寸并生成响应式属性:
<img><NuxtImg>@nuxt/imagesizeshtml
<!-- 首屏/LCP图片 -->
<NuxtImg
src="/hero.jpg"
format="webp"
preload
loading="eager"
fetch-priority="high"
width="1200"
height="600"
/>
<!-- 非首屏图片 -->
<NuxtImg
src="/feature.jpg"
format="webp"
loading="lazy"
fetch-priority="low"
width="600"
height="400"
/>始终设置和以避免布局偏移(CLS)。
widthheightFonts: Use Nuxt Fonts
字体:使用Nuxt Fonts
Add to automatically self-host fonts, inject rules, and generate fallback metrics that minimize CLS. No manual required.
@nuxt/fonts@font-face<link rel="preload">添加可自动托管字体、注入规则,并生成最小化CLS的回退指标。无需手动添加。
@nuxt/fonts@font-face<link rel="preload">Third-Party Scripts: Use Nuxt Scripts
第三方脚本:使用Nuxt Scripts
Add to load analytics, embeds, and social widgets without blocking the main thread. Scripts support deferred triggers and typed proxies:
@nuxt/scriptsts
const { proxy } = useScriptGoogleAnalytics({
id: 'G-XXXXXXXX',
scriptOptions: { trigger: 'manual' },
})
// Safe to call before script loads — events are queued
proxy.gtag('event', 'page_view')添加可加载分析工具、嵌入内容和社交组件,且不会阻塞主线程。脚本支持延迟触发和类型化代理:
@nuxt/scriptsts
const { proxy } = useScriptGoogleAnalytics({
id: 'G-XXXXXXXX',
scriptOptions: { trigger: 'manual' },
})
// 脚本加载前即可安全调用——事件会被排队
proxy.gtag('event', 'page_view')Leverage Smart Prefetching via <NuxtLink>
<NuxtLink>通过<NuxtLink>
利用智能预获取
<NuxtLink><NuxtLink>ts
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: { prefetchOn: 'interaction' },
},
},
})<NuxtLink>ts
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: { prefetchOn: 'interaction' },
},
},
})Apply Vue-Level Optimizations
应用Vue层面的优化
Nuxt apps are Vue apps — apply Vue performance primitives:
- /
shallowReffor large objects not needing deep reactivityshallowReactive - for static subtrees that never change
v-once - to skip re-renders when dependencies are unchanged
v-memo - to cache derived state rather than recalculating in templates
computed
Nuxt应用本质是Vue应用——可应用Vue性能原语:
- 对于无需深度响应式的大型对象,使用/
shallowRefshallowReactive - 对于永不改变的静态子树,使用
v-once - 当依赖未变化时,使用跳过重渲染
v-memo - 使用缓存派生状态,而非在模板中重复计算
computed
Auto-Imports
自动导入
Nuxt auto-imports components from , composables from , and utilities from . Only used exports appear in the production bundle — no manual tree-shaking needed.
app/components/app/composables/app/utils/Place server-only utilities in — they are also auto-imported within the directory.
server/utils/server/To make imports explicit (useful for clarity or monorepos), use the alias:
#importsts
import { ref, computed, useFetch } from '#imports'Nuxt会自动导入中的组件、中的composable,以及中的工具函数。只有被使用的导出才会出现在生产包中——无需手动摇树优化。
app/components/app/composables/app/utils/仅服务端使用的工具函数可放在中——它们也会在目录下自动导入。
server/utils/server/若需要显式导入(便于清晰理解或用于 monorepo),可使用别名:
#importsts
import { ref, computed, useFetch } from '#imports'Common Pitfalls
常见陷阱
| Problem | Solution |
|---|---|
| Double data fetch (server + client) | Use |
| Plugins blocking hydration | Move non-global logic to composables |
| Large bundles | Run |
| Layout shift from images | Always set |
| Unoptimized fonts | Add |
| INP degradation from third-party scripts | Add |
| Deep reactivity on large objects | Use |
Composable called after | Call composables synchronously before async operations |
| Unused dependencies bloating bundle | Audit |
| 问题 | 解决方案 |
|---|---|
| 数据重复获取(服务端+客户端) | 使用 |
| 插件阻塞水合 | 将非全局逻辑移至composable |
| 包体积过大 | 运行 |
| 图片导致布局偏移 | 始终为 |
| 字体未优化 | 添加 |
| 第三方脚本导致INP下降 | 添加 |
| 大型对象使用深度响应式 | 使用 |
在 | 在异步操作前同步调用composable |
| 未使用的依赖导致包体积膨胀 | 审核 |
Profiling Workflow
性能分析流程
- Bundle analysis — generates a visual treemap; identify large dependencies.
npx nuxi analyze - Nuxt DevTools — Timeline, Render Tree, and Inspect tabs reveal component render costs and file sizes.
- Chrome DevTools — Performance panel shows LCP/CLS live; Lighthouse gives actionable scores.
- PageSpeed Insights — Combine lab + real-world field data for production auditing.
- WebPageTest — Test from multiple global regions and network conditions.
- 包分析 — 会生成可视化树形图;可识别大型依赖。
npx nuxi analyze - Nuxt DevTools — 时间线、渲染树和检查面板可展示组件渲染成本和文件大小。
- Chrome DevTools — 性能面板可实时查看LCP/CLS;Lighthouse可提供可执行的评分。
- PageSpeed Insights — 结合实验室数据和真实场景数据进行生产环境审核。
- WebPageTest — 从全球多个地区和网络条件下进行测试。
Additional Resources
额外资源
Reference Files
参考文件
- — Detailed breakdown of all performance techniques,
references/performance.mdoptions, and Core Web Vitals targetsrouteRules - — In-depth rendering mode trade-offs, hydration mismatch prevention, and deployment targets
references/rendering.md
- — 所有性能技术、
references/performance.md选项和Core Web Vitals目标的详细说明routeRules - — 渲染模式的深入权衡分析、水合不匹配的预防方法以及部署目标
references/rendering.md