Browser Çalışma Mantığı ve İleri Seviye JavaScript
Frontend performansını gerçekten anlamak için tarayıcının kaputunun altına bakmak gerekir. Reflow'dan Event Loop'a, Closure'dan Inheritance'a kadar derinlemesine bir teknik yolculuk.
1. Browser Rendering Pipeline
Reflow (Layout) vs Repaint
Reflow: DOM ağacındaki bir elemanın boyutu veya konumu değiştiğinde, tarayıcının sayfa düzenini (layout) yeniden hesaplaması işlemidir. Çok maliyetlidir çünkü etkilenen tüm çocuk ve komşu elementlerin de yeniden hesaplanmasını tetikler.
Repaint: Elemanın görünümü (renk, gölge vb.) değiştiğinde, ancak geometrisi (boyut/konum) değişmediğinde gerçekleşir. Reflow'a göre daha ucuzdur.
div.style.width = '100px'; console.log(div.offsetWidth);), tarayıcı o anki değeri verebilmek için bekleyen tüm layout işlemlerini zorla çalıştırır. Bu performans katilidir. Neden Transform Reflow Yapmaz?
transform ve opacity özellikleri, tarayıcının Compositor Thread katmanında işlenir (GPU hızlandırmalı). Ana thread'i (Main Thread) meşgul etmeden, mevcut katmanların (layers) sadece görsel olarak manipüle edilmesini sağlar. Bu yüzden animasyonlarda her zaman top/left yerine transform: translate() kullanmalıyız.
2. Performans Teknikleri
Virtual Scroll
Binlerce elemanlı bir listede, DOM'da sadece kullanıcının o an gördüğü (viewport) elemanları tutma tekniğidir. Kullanıcı kaydırdıkça, üstten çıkan elemanlar DOM'dan silinir ve alta yeni gelenler eklenir. Bu sayede DOM boyutu sabit kalır ve bellek şişmez.
Throttle vs Debounce
- Throttle (Musluk): İşlemin belirli aralıklarla (örn: her 200ms'de bir) çalışmasını sağlar. Scroll eventlerinde idealdir.
- Debounce (Bekleme): İşlem bittikten belirli bir süre sonra çalışır. Kullanıcı yazmayı bitirdiğinde çalışan arama kutularında (Search Input) kullanılır.
Intersection Observer
Bir elemanın görünür olup olmadığını (viewport'a girip girmediğini) izlemek için kullanılan modern API'dir. Eskiden scroll event listener ile yapılan maliyetli hesaplamaların yerine geçer. Lazy loading ve sonsuz kaydırma (infinite scroll) için standarttır.
3. JavaScript Core & Event Loop
Event Loop Nasıl Çalışır?
JavaScript Single Threaded (tek iş parçacıklı) bir dildir. Yani aynı anda sadece bir işlem yapabilir. Asenkron işlemleri yönetmek için Event Loop mekanizmasını kullanır.
- Call Stack: Çalışan kodun takibi.
- Web APIs: Tarayıcının sağladığı asenkron özellikler (setTimeout, fetch, DOM events).
- Callback Queue (Macrotasks):
setTimeout,setIntervalgibi işlemlerin callback'leri burada bekler. - Microtask Queue:
Promise,queueMicrotaskgibi işlemler burada bekler. Önceliği Macrotask'ten yüksektir.
Event Loop sürekli döner; Call Stack boşaldığında önce Microtask kuyruğunu tamamen bitirir, sonra Macrotask kuyruğundan bir işlem alır.
Closure Nedir?
Bir fonksiyonun, kendi kapsamı (scope) dışındaki değişkenlere, o dış kapsam sonlansa bile erişebilme yeteneğidir. Veri gizliliği (private variables) ve state koruma için kullanılır.
function sayacYap() {
let count = 0; // Private değişken
return function() {
count++;
return count;
}
}
const sayac = sayacYap();
console.log(sayac()); // 1
console.log(sayac()); // 2
// count değişkenine dışarıdan erişilemez, sadece dönen fonksiyon erişebilir.
Inheritance & Prototype Chain
JavaScript'te sınıflar (Class) aslında "Syntactic Sugar"dır. Arka planda her şey Prototypal Inheritance ile çalışır. Her nesnenin bir __proto__ özelliği vardır ve bu zincirleme olarak yukarı doğru (Object.prototype'a kadar) gider. Bir özellik nesnede bulunamazsa, zincirdeki bir üst prototipte aranır.