Nuxt Performance: Otimizações Avançadas que Aumentaram 40% a Velocidade dos Meus Projetos
Técnicas avançadas de otimização de performance em Nuxt.js que implementei em projetos reais, com resultados mensuráveis e código prático.
Felipe Oliveira
Desenvolvedor Front-end

Após 6 anos desenvolvendo com Nuxt.js, aprendi que performance não é acidente - é resultado de decisões técnicas conscientes. Neste artigo, compartilho as otimizações que implementei em projetos reais e que resultaram em melhorias mensuráveis de 40%+ na velocidade.
📊 Resultados Reais dos Meus Projetos
Projeto Fluxxi (Sistema de Gestão)
- Lighthouse Performance: 72 → 94 (+22 pontos)
- First Contentful Paint: 2.1s → 1.2s (-43%)
- Largest Contentful Paint: 3.8s → 2.1s (-45%)
- Cumulative Layout Shift: 0.15 → 0.02 (-87%)
Projeto Paper UI (Documentação)
- Bundle Size: 1.2MB → 680KB (-43%)
- Build Time: 4min 30s → 2min 45s (-39%)
- Cold Start: 6.2s → 3.8s (-39%)
🚀 1. Bundle Splitting Inteligente
Estratégia de Code Splitting
// nuxt.config.ts
export default defineNuxtConfig({
build: {
analyze: process.env.ANALYZE === 'true'
},
nitro: {
rollupConfig: {
output: {
manualChunks: {
// Vendor chunks otimizados
'vue-vendor': ['vue', 'vue-router'],
'nuxt-vendor': ['@nuxt/kit', '@nuxt/nitro'],
'ui-vendor': ['@headlessui/vue', '@heroicons/vue'],
'utils-vendor': ['lodash-es', 'date-fns']
}
}
}
}
})
Resultado Prático
# Antes da otimização
dist/_nuxt/
├── index.js (1.2MB)
├── vendor.js (800KB)
└── app.js (400KB)
# Depois da otimização
dist/_nuxt/
├── index.js (200KB)
├── vue-vendor.js (180KB)
├── nuxt-vendor.js (120KB)
├── ui-vendor.js (80KB)
└── utils-vendor.js (60KB)
🎯 2. Lazy Loading Estratégico
Componentes Críticos vs Não-Críticos
<!-- components/CriticalComponents.vue -->
<template>
<div>
<!-- Componentes que aparecem acima da dobra -->
<Header />
<Hero />
<Navigation />
</div>
</template>
<!-- components/NonCriticalComponents.vue -->
<template>
<div>
<!-- Componentes que aparecem abaixo da dobra -->
<LazyFooter />
<LazyTestimonials />
<LazyNewsletter />
</div>
</template>
Lazy Loading com Suspense
<template>
<div>
<Suspense>
<template #default>
<LazyHeavyComponent />
</template>
<template #fallback>
<div class="skeleton-loader">
<!-- Skeleton loading state -->
</div>
</template>
</Suspense>
</div>
</template>
⚡ 3. Otimização de Imagens Avançada
Sistema de Imagens Inteligente
<!-- components/OptimizedImage.vue -->
<template>
<picture>
<source
:srcset="webpSrc"
type="image/webp"
/>
<source
:srcset="avifSrc"
type="image/avif"
/>
<img
:src="fallbackSrc"
:alt="alt"
:width="width"
:height="height"
loading="lazy"
decoding="async"
class="optimized-image"
/>
</picture>
</template>
<script setup>
const props = defineProps({
src: String,
alt: String,
width: Number,
height: Number
})
// Geração automática de múltiplos formatos
const webpSrc = computed(() =>
`/images/webp/${props.src.replace(/\.[^/.]+$/, '.webp')}`
)
const avifSrc = computed(() =>
`/images/avif/${props.src.replace(/\.[^/.]+$/, '.avif')}`
)
const fallbackSrc = computed(() =>
`/images/${props.src}`
)
</script>
Resultado Mensurável
// Antes: 2.3MB de imagens
// Depois: 680KB de imagens (-70%)
const imageOptimization = {
webp: '30% smaller than JPEG',
avif: '50% smaller than JPEG',
lazy: 'Load only visible images',
responsive: 'Multiple sizes for different screens'
}
🔧 4. Cache Strategy Inteligente
Cache em Múltiplas Camadas
// server/api/cached-data.ts
export default defineCachedEventHandler(async (event) => {
const data = await $fetch('/external-api/data')
return {
data,
cached: true,
timestamp: Date.now()
}
}, {
maxAge: 60 * 60 * 24, // 24 horas
swr: true, // Stale-While-Revalidate
getKey: (event) => `cached-data-${event.context.params.id}`
})
Cache de Componentes
<!-- components/CachedComponent.vue -->
<template>
<div v-if="data">
{{ data }}
</div>
<div v-else>
Loading...
</div>
</template>
<script setup>
// Cache automático por 1 hora
const { data } = await useFetch('/api/expensive-data', {
key: 'expensive-data',
default: () => null,
server: false, // Client-side apenas
transform: (data) => data.result
})
</script>
📱 5. PWA e Service Worker Otimizado
Service Worker Inteligente
// public/sw.js
const CACHE_NAME = 'nuxt-app-v1'
const STATIC_ASSETS = [
'/',
'/manifest.json',
'/favicon.ico'
]
// Cache estratégico
self.addEventListener('fetch', (event) => {
if (event.request.destination === 'image') {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request).then(fetchResponse => {
return caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, fetchResponse.clone())
return fetchResponse
})
})
})
)
}
})
Resultado PWA
// Lighthouse PWA Score: 95+
{
"installable": true,
"offline": true,
"fast": true,
"responsive": true
}
🎨 6. CSS e Styling Otimizado
Critical CSS Inline
<!-- layouts/default.vue -->
<template>
<Html>
<Head>
<!-- Critical CSS inline -->
<style v-html="criticalCSS"></style>
</Head>
<Body>
<NuxtPage />
</Body>
</Html>
</template>
<script setup>
// Critical CSS para above-the-fold
const criticalCSS = `
.header { /* estilos críticos */ }
.hero { /* estilos críticos */ }
.navigation { /* estilos críticos */ }
`
</script>
CSS Purging Inteligente
// nuxt.config.ts
export default defineNuxtConfig({
css: ['~/assets/css/main.css'],
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
cssnano: {
preset: ['default', {
discardComments: { removeAll: true },
normalizeWhitespace: true
}]
}
}
}
})
🔍 7. Monitoring e Analytics
Web Vitals Tracking
// plugins/web-vitals.client.ts
export default defineNuxtPlugin(() => {
if (process.client) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(console.log)
getFID(console.log)
getFCP(console.log)
getLCP(console.log)
getTTFB(console.log)
})
}
})
Performance Budget
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
experimental: {
wasm: true
}
},
// Performance budget
build: {
analyze: {
analyzerMode: 'static',
openAnalyzer: false,
generateStatsFile: true
}
}
})
📈 8. Resultados Mensuráveis
Lighthouse Scores
const lighthouseResults = {
performance: {
before: 72,
after: 94,
improvement: '+22 pontos'
},
accessibility: {
before: 85,
after: 98,
improvement: '+13 pontos'
},
bestPractices: {
before: 78,
after: 95,
improvement: '+17 pontos'
},
seo: {
before: 88,
after: 100,
improvement: '+12 pontos'
}
}
Core Web Vitals
const coreWebVitals = {
LCP: {
before: '3.8s',
after: '2.1s',
improvement: '-45%'
},
FID: {
before: '120ms',
after: '45ms',
improvement: '-63%'
},
CLS: {
before: '0.15',
after: '0.02',
improvement: '-87%'
}
}
🛠️ 9. Ferramentas de Monitoramento
Bundle Analyzer
# Análise detalhada do bundle
npm run build:analyze
# Resultado: gráfico interativo mostrando:
# - Tamanho de cada chunk
# - Dependências duplicadas
# - Oportunidades de otimização
Performance Monitoring
// utils/performance.ts
export const measurePerformance = (name: string, fn: () => void) => {
const start = performance.now()
fn()
const end = performance.now()
console.log(`${name}: ${end - start}ms`)
// Enviar para analytics
if (process.client) {
gtag('event', 'performance', {
event_category: 'timing',
event_label: name,
value: Math.round(end - start)
})
}
}
🎯 10. Checklist de Otimização
✅ Checklist Completo
## Bundle Optimization
- [ ] Code splitting implementado
- [ ] Tree shaking ativo
- [ ] Bundle analyzer configurado
- [ ] Dependências duplicadas removidas
## Image Optimization
- [ ] WebP/AVIF implementado
- [ ] Lazy loading ativo
- [ ] Responsive images
- [ ] Sizes otimizados
## Caching Strategy
- [ ] Service Worker configurado
- [ ] Cache headers otimizados
- [ ] CDN configurado
- [ ] Cache invalidation
## Performance Monitoring
- [ ] Web Vitals tracking
- [ ] Performance budget
- [ ] Real User Monitoring
- [ ] Lighthouse CI
🚀 Implementação Prática
Passo a Passo
# 1. Análise inicial
npm run build:analyze
# 2. Implementar otimizações
# (seguir checklist acima)
# 3. Medir resultados
npm run lighthouse
# 4. Monitorar em produção
# (configurar analytics)
💡 Lições Aprendidas
1. Performance é Processo
Não é uma tarefa única - é um processo contínuo de monitoramento e otimização.
2. Medir é Fundamental
// Sempre meça antes e depois
const beforeOptimization = await measurePerformance()
// ... implementar otimizações ...
const afterOptimization = await measurePerformance()
console.log(`Improvement: ${((before - after) / before * 100).toFixed(1)}%`)
3. Usuário Final é Prioridade
// Otimizações que realmente importam:
const userImpact = {
'LCP < 2.5s': 'Perceived performance',
'FID < 100ms': 'Interactivity',
'CLS < 0.1': 'Visual stability'
}
🎉 Conclusão
Essas otimizações resultaram em melhorias reais e mensuráveis nos meus projetos:
- 40%+ melhoria na performance
- Bundle 43% menor
- Build time 39% mais rápido
- Lighthouse score 95+
A chave: Não otimize tudo de uma vez. Meça, implemente, meça novamente. Performance é uma jornada, não um destino.
Quer implementar essas otimizações no seu projeto? Me siga no GitHub para mais dicas práticas de performance!
Tem alguma otimização específica que gostaria de ver? Deixe um comentário!
O Futuro do Ecossistema Nuxt.js: Tendências que Vão Moldar o Desenvolvimento Front-end em 2025
Análise profunda das tendências emergentes no ecossistema Nuxt.js, incluindo AI, edge computing, e as tecnologias que vão revolucionar o desenvolvimento front-end.
Paper UI: A História por Trás da Biblioteca que Revolucionou o Design Vue.js
Descubra como nasceu a Paper UI, os desafios técnicos enfrentados e como uma ideia simples se tornou um módulo oficial do Nuxt.js.