Nuxt.js Performance Optimization
Master Nuxt 3 performance with server-side rendering, Nitro engine, auto-imports, and Vue 3 Composition API best practices.
Why Nuxt Performance Matters
Nuxt 3 is built on Vue 3 and the Nitro engine, offering excellent performance out of the box. However, proper configuration and understanding of Nuxt's features can take your application's speed and Core Web Vitals to the next level.
Nitro Engine
Blazing-fast server engine with universal deployment.
Auto-imports
Automatic tree-shaking with smart auto-imports.
Hybrid Rendering
Mix SSR, SSG, and SPA modes per route.
Vue 3 Optimization
Composition API and script setup for better performance.
1. Leverage Server-Side Rendering
Nuxt 3's SSR capabilities improve initial load time and SEO:
Use Server Routes for Data Fetching
<script setup>const { data: posts } = await useFetch('/api/posts');</script>
<template> <div v-for="post in posts" :key="post.id"> {{ post.title }} </div></template>API Routes with Nitro
// server/api/posts.tsexport default defineEventHandler(async (event) => { const posts = await getPosts(); return posts;});Hybrid Rendering
// nuxt.config.tsexport default defineNuxtConfig({ routeRules: { '/': { prerender: true }, // SSG '/blog/**': { swr: 3600 }, // ISR with 1-hour cache '/api/**': { cors: true }, '/admin/**': { ssr: false }, // SPA mode },});2. Optimize Auto-Imports and Tree-Shaking
Nuxt 3's auto-imports are optimized by default but can be fine-tuned:
Component Auto-Imports
// components/TheHeader.vue - automatically imported<script setup>// No import needed for composablesconst route = useRoute();const config = useRuntimeConfig();</script>
<template> <header>Navigation</header></template>Lazy Load Components
<template> <div> <!-- Lazy load with Lazy prefix --> <LazyHeavyComponent v-if="showHeavy" />
<!-- Or use built-in lazy loading --> <ClientOnly> <HeavyChart /> <template #fallback> <Loading /> </template> </ClientOnly> </div></template>Configure Auto-Imports
// nuxt.config.tsexport default defineNuxtConfig({ imports: { dirs: [ 'composables/**', 'utils/**', ], }, components: { dirs: [ { path: '~/components/global', global: true, }, '~/components', ], },});3. Image Optimization with Nuxt Image
Use @nuxt/image for automatic image optimization:
Install and Configure
# Installnpm install @nuxt/image
# nuxt.config.tsexport default defineNuxtConfig({ modules: ['@nuxt/image'], image: { formats: ['webp', 'avif'], quality: 80, },});Use NuxtImg and NuxtPicture
<template> <!-- Basic usage --> <NuxtImg src="/hero.jpg" alt="Hero" width="800" height="600" />
<!-- Responsive images --> <NuxtPicture src="/hero.jpg" alt="Hero" :img-attrs="{ class: 'hero-image' }" sizes="xs:100vw sm:100vw md:50vw lg:400px" />
<!-- Lazy loading --> <NuxtImg src="/below-fold.jpg" loading="lazy" /></template>4. Optimize JavaScript Bundle
Reduce bundle size with code splitting and dynamic imports:
Code Splitting
// nuxt.config.tsexport default defineNuxtConfig({ build: { splitChunks: { layouts: true, pages: true, commons: true, }, }, vite: { build: { rollupOptions: { output: { manualChunks: { 'chart-library': ['chart.js'], }, }, }, }, },});Analyze Bundle
# Install analyzernpm install -D nuxt-build-analyzer
# nuxt.config.tsexport default defineNuxtConfig({ modules: ['nuxt-build-analyzer'],});
# Run analysisnuxt build --analyze5. Caching and State Management
Implement effective caching strategies:
useState for Client-Side State
<script setup>// Shared state across componentsconst counter = useState('counter', () => 0);
// Persist state during SSR hydrationconst user = useState('user', () => ({ name: 'Guest', loggedIn: false,}));</script>useFetch with Caching
<script setup>const { data } = await useFetch('/api/posts', { key: 'posts', // Cache for 1 hour getCachedData: (key) => { const data = nuxtApp.payload.data[key] || nuxtApp.static.data[key]; if (data && Date.now() - data.fetchedAt < 3600000) { return data; } },});</script>Server-Side Caching
// server/api/posts.tsimport { defineCachedEventHandler } from '#nitro';
export default defineCachedEventHandler(async (event) => { const posts = await getPosts(); return posts;}, { maxAge: 60 * 60, // 1 hour getKey: () => 'posts',});6. Vue 3 Composition API Best Practices
Optimize component performance with modern Vue patterns:
- •Use
script setupfor better performance and smaller bundles - •Avoid unnecessary reactive() wrapping for static data
- •Use computed() for derived state instead of watchers
- •Implement v-once for static content that never changes
- •Use shallowRef() and shallowReactive() for large datasets
Optimized Component Example
<script setup>import { computed, shallowRef } from 'vue';
// Shallow reactivity for large arraysconst items = shallowRef([]);
// Computed for derived stateconst filteredItems = computed(() => items.value.filter(item => item.active));</script>
<template> <div> <div v-for="item in filteredItems" :key="item.id"> {{ item.title }} </div> </div></template>7. Performance Monitoring
Track performance with built-in tools:
- •Use Nuxt DevTools for component performance insights
- •Enable Vue DevTools for reactivity tracking
- •Monitor Core Web Vitals with web-vitals library
- •Use Lighthouse CI in your deployment pipeline
Analyze Your Nuxt App
Get Nuxt-specific optimization recommendations powered by AI.
Test Your Nuxt Site