nuxt

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Nuxt 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
routeRules
. Assign rendering strategies per route rather than using a single global mode:
ts
// 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:
  • prerender: true
    — generate at build time, serve as static asset
  • swr: N
    — server/proxy cache for N seconds, stale-while-revalidate
  • isr: N
    — CDN cache until next deploy (Vercel/Netlify);
    isr: true
    means persist indefinitely
  • ssr: false
    — browser-only rendering (SPA mode for that route)
  • redirect: '/new'
    — server-side redirect
  • headers: {}
    — add custom response headers (e.g., long cache on assets)
Nuxt 4通过
routeRules
支持混合渲染。可为每个路由分配单独的渲染策略,而非使用单一全局模式:
ts
// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },          // 构建时生成静态资源
    '/products/**': { swr: 3600 },     // 缓存,后台自动重新验证
    '/blog': { isr: 3600 },            // CDN缓存,每小时重新验证
    '/admin/**': { ssr: false },        // 仅客户端渲染
    '/api/**': { cors: true },
  },
})
路由规则参考:
  • prerender: true
    — 构建时生成,作为静态资源提供
  • swr: N
    — 服务器/代理缓存N秒,采用stale-while-revalidate策略
  • isr: N
    — CDN缓存至下次部署(Vercel/Netlify);
    isr: true
    表示永久缓存
  • ssr: false
    — 仅浏览器端渲染(该路由采用SPA模式)
  • 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
references/rendering.md
for a full breakdown of trade-offs and deployment targets.
部署到CDN边缘服务器(Cloudflare Workers、Vercel Edge、Netlify Edge)以降低延迟。Nuxt的Nitro引擎原生支持这些环境——无需修改代码,仅需选择不同的构建预设即可。
详细的权衡分析和部署目标可查看
references/rendering.md

Component Best Practices

组件最佳实践

Lazy-Load Non-Critical Components

懒加载非核心组件

Prefix any component with
Lazy
to defer its JavaScript until needed. This directly reduces initial bundle size and improves Time to Interactive (TTI):
html
<script setup lang="ts">
const show = ref(false)
</script>

<template>
  <div>
    <button @click="show = true">Load list</button>
    <LazyMountainsList v-if="show" />
  </div>
</template>
为任意组件添加
Lazy
前缀,可延迟其JavaScript加载至需要时。这能直接减小初始包体积,提升交互时间(TTI):
html
<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

使用
useFetch
useAsyncData

These 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
await
outside of
<script setup>
,
defineNuxtComponent
,
defineNuxtPlugin
, or
defineNuxtRouteMiddleware
:
ts
// 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依赖同步的生命周期上下文。请勿在
<script setup>
defineNuxtComponent
defineNuxtPlugin
defineNuxtRouteMiddleware
之外的
await
之后调用composable:
ts
// 不推荐
const data = await someAsyncOperation()
const config = useRuntimeConfig() // 上下文已丢失

// 推荐——在await之前调用composable,或在<script setup>内部调用
const config = useRuntimeConfig()
const data = await someAsyncOperation()

Performance Optimization

性能优化

Images: Use
<NuxtImg>

图片:使用
<NuxtImg>

Replace all
<img>
tags with
<NuxtImg>
(requires
@nuxt/image
). It auto-converts to WebP/Avif, resizes, and generates responsive
sizes
:
html
<!-- 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
width
and
height
to prevent layout shift (CLS).
将所有
<img>
标签替换为
<NuxtImg>
(需安装
@nuxt/image
)。它会自动转换为WebP/Avif格式、调整尺寸并生成响应式
sizes
属性:
html
<!-- 首屏/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"
/>
始终设置
width
height
以避免布局偏移(CLS)。

Fonts: Use Nuxt Fonts

字体:使用Nuxt Fonts

Add
@nuxt/fonts
to automatically self-host fonts, inject
@font-face
rules, and generate fallback metrics that minimize CLS. No manual
<link rel="preload">
required.
添加
@nuxt/fonts
可自动托管字体、注入
@font-face
规则,并生成最小化CLS的回退指标。无需手动添加
<link rel="preload">

Third-Party Scripts: Use Nuxt Scripts

第三方脚本:使用Nuxt Scripts

Add
@nuxt/scripts
to load analytics, embeds, and social widgets without blocking the main thread. Scripts support deferred triggers and typed proxies:
ts
const { proxy } = useScriptGoogleAnalytics({
  id: 'G-XXXXXXXX',
  scriptOptions: { trigger: 'manual' },
})
// Safe to call before script loads — events are queued
proxy.gtag('event', 'page_view')
添加
@nuxt/scripts
可加载分析工具、嵌入内容和社交组件,且不会阻塞主线程。脚本支持延迟触发和类型化代理:
ts
const { proxy } = useScriptGoogleAnalytics({
  id: 'G-XXXXXXXX',
  scriptOptions: { trigger: 'manual' },
})
// 脚本加载前即可安全调用——事件会被排队
proxy.gtag('event', 'page_view')

Leverage Smart Prefetching via
<NuxtLink>

通过
<NuxtLink>
利用智能预获取

<NuxtLink>
automatically prefetches JavaScript for in-viewport links. To reduce bandwidth on large sites, switch to interaction-based prefetching:
ts
// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    defaults: {
      nuxtLink: { prefetchOn: 'interaction' },
    },
  },
})
<NuxtLink>
会自动预获取视口内链接对应的JavaScript。对于大型站点,可切换为基于交互的预获取:
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:
  • shallowRef
    /
    shallowReactive
    for large objects not needing deep reactivity
  • v-once
    for static subtrees that never change
  • v-memo
    to skip re-renders when dependencies are unchanged
  • computed
    to cache derived state rather than recalculating in templates
Nuxt应用本质是Vue应用——可应用Vue性能原语:
  • 对于无需深度响应式的大型对象,使用
    shallowRef
    /
    shallowReactive
  • 对于永不改变的静态子树,使用
    v-once
  • 当依赖未变化时,使用
    v-memo
    跳过重渲染
  • 使用
    computed
    缓存派生状态,而非在模板中重复计算

Auto-Imports

自动导入

Nuxt auto-imports components from
app/components/
, composables from
app/composables/
, and utilities from
app/utils/
. Only used exports appear in the production bundle — no manual tree-shaking needed.
Place server-only utilities in
server/utils/
— they are also auto-imported within the
server/
directory.
To make imports explicit (useful for clarity or monorepos), use the
#imports
alias:
ts
import { ref, computed, useFetch } from '#imports'
Nuxt会自动导入
app/components/
中的组件、
app/composables/
中的composable,以及
app/utils/
中的工具函数。只有被使用的导出才会出现在生产包中——无需手动摇树优化。
仅服务端使用的工具函数可放在
server/utils/
中——它们也会在
server/
目录下自动导入。
若需要显式导入(便于清晰理解或用于 monorepo),可使用
#imports
别名:
ts
import { ref, computed, useFetch } from '#imports'

Common Pitfalls

常见陷阱

ProblemSolution
Double data fetch (server + client)Use
useFetch
/
useAsyncData
instead of raw
$fetch
Plugins blocking hydrationMove non-global logic to composables
Large bundlesRun
nuxi analyze
; lazy-load large components
Layout shift from imagesAlways set
width
/
height
on
<NuxtImg>
Unoptimized fontsAdd
@nuxt/fonts
INP degradation from third-party scriptsAdd
@nuxt/scripts
with deferred triggers
Deep reactivity on large objectsUse
shallowRef
/
shallowReactive
Composable called after
await
Call composables synchronously before async operations
Unused dependencies bloating bundleAudit
package.json
; remove unused packages
问题解决方案
数据重复获取(服务端+客户端)使用
useFetch
/
useAsyncData
替代原生
$fetch
插件阻塞水合将非全局逻辑移至composable
包体积过大运行
nuxi analyze
;懒加载大型组件
图片导致布局偏移始终为
<NuxtImg>
设置
width
/
height
字体未优化添加
@nuxt/fonts
第三方脚本导致INP下降添加
@nuxt/scripts
并使用延迟触发
大型对象使用深度响应式使用
shallowRef
/
shallowReactive
await
之后调用Composable
在异步操作前同步调用composable
未使用的依赖导致包体积膨胀审核
package.json
;移除未使用的包

Profiling Workflow

性能分析流程

  1. Bundle analysis
    npx nuxi analyze
    generates a visual treemap; identify large dependencies.
  2. Nuxt DevTools — Timeline, Render Tree, and Inspect tabs reveal component render costs and file sizes.
  3. Chrome DevTools — Performance panel shows LCP/CLS live; Lighthouse gives actionable scores.
  4. PageSpeed Insights — Combine lab + real-world field data for production auditing.
  5. WebPageTest — Test from multiple global regions and network conditions.
  1. 包分析
    npx nuxi analyze
    会生成可视化树形图;可识别大型依赖。
  2. Nuxt DevTools — 时间线、渲染树和检查面板可展示组件渲染成本和文件大小。
  3. Chrome DevTools — 性能面板可实时查看LCP/CLS;Lighthouse可提供可执行的评分。
  4. PageSpeed Insights — 结合实验室数据和真实场景数据进行生产环境审核。
  5. WebPageTest — 从全球多个地区和网络条件下进行测试。

Additional Resources

额外资源

Reference Files

参考文件

  • references/performance.md
    — Detailed breakdown of all performance techniques,
    routeRules
    options, and Core Web Vitals targets
  • references/rendering.md
    — In-depth rendering mode trade-offs, hydration mismatch prevention, and deployment targets
  • references/performance.md
    — 所有性能技术、
    routeRules
    选项和Core Web Vitals目标的详细说明
  • references/rendering.md
    — 渲染模式的深入权衡分析、水合不匹配的预防方法以及部署目标