Nuxt 3'te Performance Optimizasyonu: Gerçek Vaka Analizleri
Modern web uygulamalarında performance, kullanıcı deneyiminin en kritik faktörlerinden biri. Bu yazıda teorik bilgilerden ziyade, gerçek projelerimde ölçülebilir sonuçlar aldığım optimizasyon tekniklerine odaklanacağım.
1. Bundle Size Optimizasyonu
Kim Var projesinde ilk deploy'dan sonra bundle size'ın 2.1MB olduğunu fark ettim. Bu, özellikle mobil kullanıcılar için kabul edilemezdi. İşte uyguladığım optimizasyon adımları:
Dynamic Import ile Lazy Loading
// pages/admin/index.vue - Before
import AdminDashboard from '~/components/AdminDashboard.vue'
import AdminUsers from '~/components/AdminUsers.vue'
// After - Dynamic imports
const AdminDashboard = defineAsyncComponent(() => import('~/components/AdminDashboard.vue'))
const AdminUsers = defineAsyncComponent(() => import('~/components/AdminUsers.vue'))
// Nuxt 3 syntax
const AdminDashboard = defineAsyncComponent({
loader: () => import('~/components/AdminDashboard.vue'),
loadingComponent: LoadingSpinner,
delay: 200,
timeout: 3000
})
Tree Shaking ile Unused Code Elimination
// Before - Tüm lodash import
import _ from 'lodash'
const result = _.debounce(searchFunction, 300)
// After - Specific import
import { debounce } from 'lodash-es'
const result = debounce(searchFunction, 300)
// nuxt.config.ts optimizasyonu
export default defineNuxtConfig({
build: {
transpile: ['lodash-es']
}
})
Sonuç: Bundle size 2.1MB'dan 890KB'a düştü (%58 azalma). First Contentful Paint 3.2s'den 1.8s'ye indi.
2. Image Optimization
Takipp projesinde ürün görselleri yüzünden sayfa yükleme süreleri çok uzundu. Modern image optimization teknikleri ile dramatik iyileştirmeler elde ettim.
Nuxt Image Modülü Konfigürasyonu
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/image'],
image: {
screens: {
xs: 320,
sm: 640,
md: 768,
lg: 1024,
xl: 1280
},
densities: [1, 2],
quality: 80,
format: ['webp', 'jpg'],
domains: ['api.takipp.com']
}
})
Component'te Kullanım
<template>
<div class="product-grid">
<div v-for="product in products" :key="product.id" class="product-card">
<NuxtImg
:src="product.image"
:alt="product.name"
width="300"
height="200"
format="webp"
quality="80"
sizes="sm:100vw md:50vw lg:33vw"
loading="lazy"
class="product-image"
/>
</div>
</div>
</template>
Ölçülebilir Sonuç: Largest Contentful Paint 4.7s'den 2.1s'ye düştü. Mobile PageSpeed Score 68'den 94'e çıktı.
3. API Response Caching: Kim Var Backend Entegrasyonu
Go backend ile Nuxt frontend arasında efficient caching mekanizması kurdum:
useFetch ile Intelligent Caching
// Smart caching with useFetch
const { data: posts, refresh } = await useFetch('/api/posts', {
key: 'blog-posts',
server: true,
default: () => [],
transform: (data) => {
return data.map(post => ({
...post,
readTime: calculateReadTime(post.content)
}))
}
})
// Conditional refresh
const refreshPosts = () => {
const lastFetch = useSessionStorage('posts-last-fetch', 0)
const now = Date.now()
if (now - lastFetch.value > 300000) { // 5 min cache
refresh()
lastFetch.value = now
}
}
Performans Artışı: API response time 800ms'den 120ms'ye düştü. Server load %70 azaldı.
4. Runtime Performance: Takipp Dashboard Optimizasyonu
Büyük data setleri ile çalışırken runtime performance sorunları yaşadım. Debouncing ile çözdüm:
Search Debouncing
// Search with debouncing
import { debounce } from 'lodash-es'
const searchTerm = ref('')
const searchResults = ref([])
const isSearching = ref(false)
// Debounced search function
const debouncedSearch = debounce(async (query) => {
if (!query.trim()) {
searchResults.value = []
return
}
isSearching.value = true
try {
const { data } = await $fetch('/api/search', {
query: { q: query, limit: 20 }
})
searchResults.value = data
} catch (error) {
console.error('Search error:', error)
} finally {
isSearching.value = false
}
}, 300)
// Watch search term changes
watch(searchTerm, (newTerm) => {
debouncedSearch(newTerm)
})
5. CSS Optimization ve Critical CSS
Tailwind CSS kullanırken karşılaştığım CSS bloat problemini çözmek için:
Tailwind Purge Konfigürasyonu
// tailwind.config.js - Optimized purging
module.exports = {
content: [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./nuxt.config.{js,ts}',
'./app.vue'
],
safelist: [
'bg-red-500',
'bg-green-500',
'text-sm',
'text-lg',
/^grid-cols-/
]
}
Sonuçlar ve Öğrendiklerim
Ölçülebilir Sonuçlar
- • Bundle size: Ortalama %60 azalma
- • FCP: 3.2s → 1.8s
- • LCP: 4.7s → 2.1s
- • PageSpeed Score: 68 → 94
- • Server response: 800ms → 120ms
Kritik Öğrendiklerim
- • Measure first, optimize second
- • Bundle analyzer kullanmadan optimizasyon yapma
- • Image optimization en büyük impact
- • Caching strategy çok kritik
- • User experience > perfect metrics
Bu optimizasyonlar gerçek projelerimde uyguladığım ve ölçülebilir sonuçlar aldığım tekniklerdir. Her projenin kendine özgü ihtiyaçları olduğunu unutmayın - önce ölçün, sonra optimize edin.