Önce ölç, sonra optimize et
Tahmin yerine performance API kullan:
performance.mark("start");
isYap();
performance.mark("end");
performance.measure("isYap", "start", "end");
console.log(performance.getEntriesByName("isYap"));Tarayıcı DevTools → Performance sekmesi de güçlü bir araçtır.
Algoritma > mikro-optimizasyon
// O(n²) — büyüyünce can sıkar
for (const item of list) {
if (otherList.includes(item)) { ... }
}
// O(n) — çok daha hızlı
const set = new Set(otherList);
for (const item of list) {
if (set.has(item)) { ... }
}map vs for micro-bench'iyle uğraşmadan önce algoritmayı düzelt.
Memoization
Aynı argümanlarla çağrılan saf fonksiyonun sonucunu cache'le:
function memoize(fn) {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn(...args);
cache.set(key, result);
return result;
};
}
const fibCache = memoize(function fib(n) {
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
});Lazy yükleme
Modülleri ihtiyaç olunca yükle:
button.onclick = async () => {
const { showModal } = await import("./heavyModal.js");
showModal();
};Bundle boyutunu küçük tutar.
DOM erişimini topla
DOM okuma/yazma layout reflow tetikler. Birden fazla işlem varsa toplu yap:
// ❌ kötü: her satırda reflow
items.forEach((item) => {
const div = document.createElement("div");
div.textContent = item;
list.appendChild(div);
});
// ✅ iyi: fragment ile tek seferde
const frag = document.createDocumentFragment();
items.forEach((item) => {
const div = document.createElement("div");
div.textContent = item;
frag.appendChild(div);
});
list.appendChild(frag);Memory leak'ten kaçın
Yaygın leak kaynakları:
- Tutulan event listener'lar — component kaldırıldı ama listener document'ta kaldı
- Closure'da büyük data — arrow function dış scope'tan büyük objeyi referans tutuyor
- setInterval / setTimeout unutulduğunda
- Global cache'ler —
WeakMapkullan, sonsuz büyümesin
// Cleanup şart
const ctrl = new AbortController();
window.addEventListener("scroll", h, { signal: ctrl.signal });
// component unmount → ctrl.abort()Saf fonksiyonlar
- Test edilmesi kolay
- Cache'lenebilir
- Paralel çalıştırılabilir
- Hata ayıklamak kolay
// ❌ saf değil
let total = 0;
function add(n) { total += n; }
// ✅ saf
function add(state, n) { return state + n; }Erken return (early exit)
// ❌ iç içe
function calc(user) {
if (user) {
if (user.active) {
// ...iş
}
}
}
// ✅ guard clause
function calc(user) {
if (!user) return;
if (!user.active) return;
// ...iş
}Type-safety: TypeScript düşün
JavaScript'in dinamik yapısı küçük projede süpriz, büyük projede ızdırap. 3+ kişiyle çalıştığın bir kod tabanın varsa TypeScript'e geç. Aynı dili yazmaya devam edersin, ekstra olarak runtime hatalarının çoğunu compile time'da yakalarsın.
Eslint + Prettier
- ESLint — bug'a açık pattern'leri yakalar
- Prettier — formatlama tartışmasını bitirir
Yeni projeye otomatik kur:
npm i -D eslint prettierErken optimizasyona düşme
Knuth'un sözü: "Erken optimizasyon tüm kötülüklerin anasıdır."
Önce çalışan, okunabilir kod yaz. Sonra ölç. Sonra darboğazı düzelt. İçinden geçen veri yolu zaten 10ms'den hızlıysa, micro-optimization uğraşmaya değmez.
- Algoritmayı düzelt
- Lazy yükle
- DOM erişimini topla
- Memory leak'i kapat
- Saf fonksiyon yaz
- Ölçmeden optimize etme
Bu sıra önemli.