Vue.js Optimizasyonunda Ölçüm Önce Gelir
Vue uygulamalarında optimizasyon, kod yazmaya başlamadan önce yavaşlığın nerede olduğunu bilmeyi gerektirir. Reaktivite, render ve paket boyutu aynı sorunun farklı katmanlarıdır; hangisinin baskın olduğunu bilmeden yapılan değişiklikler çoğu zaman ölçülebilir bir kazanç sağlamaz.
Bu rehber orta seviye geliştiriciler için hazırlandı. Vue 3 ve Composition API varsayılmıştır; Options API ile yazılmış projelerde de aynı ilkeler geçerlidir. Sürüm numarası verilmediği için burada belirli bir Vue sürümüne bağlı kalınmamıştır. Örnekler çalıştırılmış çıktılar olarak değil, davranışı göstermek için yazılmış kod parçaları olarak okunmalıdır.
Önkoşullar
- Vue 3 projesi ve bir build aracı (Vite gibi) kullanıyor olmanız
- Tarayıcı geliştirici araçlarında Performance ve Network sekmelerini temel düzeyde kullanabilmeniz
ref,reactive,computed,watchve bileşen yaşam döngüsü kavramlarına aşina olmanız
1. Ölçüm: Nereden Başlamalı
Optimizasyona başlamadan önce şu üç soruyu yanıtlayın:
- İlk yükleme mi yavaş, yoksa etkileşimden sonraki güncellemeler mi?
- Sorun paket boyutunda mı, yoksa çalışma zamanındaki render ve reaktivite maliyetinde mi?
- Tek bir bileşen mi yoksa paylaşılan bir durum mu tüm ağacı yeniden render ettiriyor?
Tarayıcı Performance kaydı, hangi işlevin ne kadar sürdüğünü gösterir. Network paneli ise hangi chunk'ların ne zaman yüklendiğini ortaya koyar. Bu iki veri olmadan yapılan değişiklikler tahminden ibarettir.
2. Reaktivite Maliyetini Azaltma
Vue'nun reaktivite sistemi, bir bağımlılık değiştiğinde ona bağlı hesaplamaları ve render efektlerini tetikler. Gereksiz bağımlılık oluşturmak, beklenmedik yeniden hesaplamalara yol açar.
computed ile Türetilmiş Veriyi Önbelleğe Alma
Şablon içinde fonksiyon çağırmak, her render'da yeniden çalıştırılmasına neden olur. Türetilmiş bir değeri computed ile tanımlamak, bağımlılıklar değişmediği sürece sonucu yeniden kullanır:
<script setup>
import { ref, computed } from 'vue'
const items = ref([])
// Her render'da yeniden hesaplanır
function totalPrice() {
return items.value.reduce((sum, item) => sum + item.price, 0)
}
// Bağımlılıklar değişene kadar önbelleğe alınır
const totalPriceCached = computed(() =>
items.value.reduce((sum, item) => sum + item.price, 0)
)
</script>
Beklenen davranış: totalPriceCached, items değişmediği sürece yeniden hesaplanmaz. totalPrice ise şablon her render edildiğinde yeniden çalışır. Liste büyüdükçe bu fark belirginleşir.
Ağır Nesneleri Derin Reaktiviteye Zorlamama
reactive ve ref varsayılan olarak derin (deep) reaktivite uygular. Yalnızca okunacak büyük veri kümeleri için bu maliyet gereksizdir:
import { shallowRef, triggerRef } from 'vue'
// İç yapısı izlenmez, yalnızca referans değişimi tetikler
const largeDataset = shallowRef([])
// Veriyi değiştirdikten sonra güncellemeyi elle tetikle
largeDataset.value.push(newItem)
triggerRef(largeDataset)
Beklenen davranış: shallowRef içindeki dizinin elemanlarının değişmesi tek başına render tetiklemez; triggerRef çağrısı güncellemeyi başlatır. Bu, büyük ve sık güncellenmeyen veri kümelerinde reaktivite izleme maliyetini düşürür.
watchEffect Yerine watch Tercih Etmek
watchEffect, çalıştığı sırada okunan tüm reaktif değerleri bağımlılık olarak kaydeder. Bu, istenmeyen tetiklemelere yol açabilir. Hangi kaynağın izlendiğini açıkça belirtmek davranışı öngörülebilir kılar:
import { watch } from 'vue'
watch(
() => props.userId,
(newId) => {
// yalnızca userId değiştiğinde çalışır
}
)
3. Render Maliyetini Kontrol Etme
v-if ve v-show Ayrımı
v-if: Koşul yanlışken DOM'da hiç öğe oluşturmaz; sık değişen koşullarda açma/kapama maliyeti yüksektir.v-show: Öğeyi oluşturur, CSS ile gizler; sık açılıp kapanan durumlarda daha ucuzdur.
Başlangıçta nadiren görünen içerik için v-if, sık değişen görünürlük için v-show uygundur.
Uzun Listelerde Sanallaştırma
Yüzlerce satırı aynı anda render etmek, hem ilk render hem güncelleme maliyetini artırır. Yalnızca görünür satırları render eden bir sanallaştırma çözümü kullanmak belirgin fark yaratır. Vue ekosisteminde yaygın sanallaştırma kütüphaneleri mevcuttur; seçim yaparken projenizin Vue sürümüyle uyumluluğunu doğrulayın.
key Kullanımı
v-for içinde key verilmemesi veya indeksin key olarak kullanılması, liste güncellemelerinde yanlış yeniden kullanıma ve gereksiz DOM işlemine yol açar. Kararlı ve benzersiz bir kimlik kullanın:
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
4. Bileşen Yükleme Stratejileri
Asenkron Bileşenler
Başlangıçta görünmeyen ağır bileşenleri defineAsyncComponent ile tembel yükleyin:
import { defineAsyncComponent } from 'vue'
const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'))
Beklenen davranış: HeavyChart bileşeni, yalnızca render edilmesi gerektiğinde ayrı bir chunk olarak yüklenir. İlk yükleme paketinin boyutu küçülür.
v-once ve Memoization
İçeriği hiç değişmeyen statik bloklar için v-once kullanılabilir; bu blok bir kez render edilir ve sonraki güncellemelerde atlanır. Ancak yanlış yerde kullanıldığında beklenmeyen güncelleme sorunlarına yol açtığı için yalnızca gerçekten statik içerikte tercih edin.
5. Paket ve Yükleme Optimizasyonu
- Route bazlı kod bölme: Sayfa bileşenlerini dinamik
importile tanımlayarak her rotanın ayrı chunk olmasını sağlayın. - Ağır bağımlılıkları gerektiğinde yükleyin: Grafik, harita veya zengin metin düzenleyici gibi kütüphaneleri yalnızca ilgili bileşen içinde dinamik olarak içe aktarın.
- Üretim derlemesi kullanın: Geliştirme modundaki uyarılar ve ek kontroller üretimde bulunmaz. Performans ölçümlerini her zaman üretim derlemesinde yapın.
Yaygın Hatalar
- Ölçüm yapmadan optimizasyona başlamak; hangi katmanın yavaş olduğunu bilmeden değişiklik yapmak.
- Şablonda ağır hesaplamaları doğrudan çağırmak;
computedkullanmamak. - Büyük veri kümelerinde gereksiz derin reaktivite kullanmak.
v-foriçinde indeksikeyolarak kullanmak.- Tüm bileşenleri tek pakette toplayıp ilk yükleme süresini şişirmek.
v-onceveyashallowRefgibi araçları, güncellenmesi gereken içerikte kullanmak.
Güvenlik Etkileri
- Dinamik bileşen yükleme ve route bazlı kod bölme, yüklenen chunk'ların güvenilir kaynaklardan geldiğinden emin olmayı gerektirir; içerik güvenlik politikası (CSP) yapılandırması bu noktada önemlidir.
v-htmlile kullanıcı kaynaklı içerik basmak, XSS riski taşır. Optimizasyon amacıyla render'dan kaçınmak içinv-htmlkullanmayın; gerekliyse içeriği güvenilir biçimde temizleyin.- Üçüncü taraf optimizasyon kütüphanelerini eklemeden önce bakım durumunu ve sürüm uyumluluğunu doğrulayın.
Kontrol Listesi
- Performans ölçümü üretim derlemesinde yapıldı mı?
- Şablondaki ağır hesaplamalar
computedile önbelleğe alındı mı? - Büyük ve seyrek güncellenen verilerde derin reaktiviteden kaçınıldı mı?
- Uzun listelerde sanallaştırma ve doğru
keykullanımı var mı? - Görünmeyen ağır bileşenler ve rotalar tembel yükleniyor mu?
v-htmlgibi riskli yapılar yalnızca güvenli içerikle mi kullanılıyor?
Optimizasyon, tek seferlik bir iş değil ölçümle beslenen bir döngüdür. Değişikliği yapın, aynı ölçümü tekrarlayın ve kazancın gerçekten oluştuğunu doğrulayın.