Kullanıcı Deneyimi Denince Milisaniyeler Savaşır.
React dünyasında iki kardeş Hook var: useEffect ve useLayoutEffect. İkisi de efekt yönetimi için kullanılır ama zamanlama farkı onları birbirinden tamamen ayırır. Bu fark milisaniyelerle ölçülür — fakat kullanıcı deneyiminde hissedilir bir fark yaratır.
Kısaca: biri sahne ışıkları yanmadan sahneye çıkar, diğeri perde arkasında işini yapar. Hangisinin ne zaman devreye girdiğini anlamak, React performansını optimize etmenin anahtarıdır.
Temel Fark
| Hook | Çalışma Zamanı | Kullanım Amacı |
|---|---|---|
| useLayoutEffect | DOM güncellendikten hemen sonra, ekran çizilmeden önce | DOM ölçümleri, senkron düzenlemeler, animasyon başlangıçları |
| useEffect | Tarayıcı çizimi tamamlandıktan sonra | Veri çekme, event listener ekleme, state kaydetme |
useLayoutEffect tarayıcı ekranı boyamadan hemen önce devreye girer. useEffect ise boyama işleminden sonra çalışır. Bu küçük fark, göz kırpma (flicker) veya UI sıçramalarını önlemede kritik rol oynar.Zamanlama Zinciri
React, bileşen render sürecinde şu sırayı izler:
- Render aşaması: React bileşenleri sanal DOM’a yazar.
- Commit aşaması: Gerçek DOM güncellenir.
- Layout Effect aşaması:
useLayoutEffectdevreye girer — DOM güncel ama henüz ekrana çizilmemiştir. - Paint aşaması: Tarayıcı ekrana yeni görünümü çizer.
- Effect aşaması:
useEffectçalışır — kullanıcı yeni görünümü artık görmektedir.
Konsol Üzerinden Gözlem
function Example() {
useLayoutEffect(() => console.log('LayoutEffect'));
useEffect(() => console.log('Effect'));
console.log('Render');
return <div>Hello</div>;
}
Konsol çıktısı:
Render
LayoutEffect
Effect
Yani
useLayoutEffect, useEffect’ten önce çalışır.Kod Üzerinden Anlamak
useLayoutEffect(() => {
console.log('LayoutEffect: DOM hazır, ama ekran çizilmeden!');
});
useEffect(() => {
console.log('Effect: Ekran çizildi, işler tamam!');
});
Bu logları konsolda incelersen fark net görünür: useLayoutEffect, DOM güncellendiği anda devreye girer; kullanıcı henüz yeni görünümü görmeden. useEffect ise kullanıcı UI’ı gördükten sonra çalışır.
Gerçek Senaryo: DOM Ölçümü
const boxRef = useRef();
useLayoutEffect(() => {
const { height } = boxRef.current.getBoundingClientRect();
console.log('Box height:', height);
});
Bu kod useEffect içinde olsaydı, kullanıcı önce eski DOM’u bir an görür, ardından güncellenmiş haliyle karşılaşırdı. O “titreme” anı, layout flicker’dır. useLayoutEffect bu sorunu ortadan kaldırır.
Ne Zaman Hangisini Kullanmalı?
| Senaryo | Doğru Hook |
|---|---|
| API’den veri çekmek | useEffect |
| Event listener ekleme / kaldırma | useEffect |
| localStorage veya analytics işlemleri | useEffect |
| DOM ölçümü veya manipülasyonu | useLayoutEffect |
| Tooltip / modal konumlandırma | useLayoutEffect |
| CSS animasyonu başlatma | useLayoutEffect |
| Görsel hizalama düzeltmesi | useLayoutEffect |
useLayoutEffect; diğer her durumda useEffect.Mini Örnek: Animasyon Öncesi Ölçüm
useEffect(() => {
const height = ref.current.offsetHeight;
startAnimation(height); // ❌ Geç kalınmış ölçüm
}, []);
Yukarıdaki kodda animasyon başlamadan önce küçük bir flicker olabilir. Ama:
useLayoutEffect(() => {
const height = ref.current.offsetHeight;
startAnimation(height); // ✅ Mükemmel zamanlama
}, []);
şeklinde yazarsan ölçüm, ekrana çizim yapılmadan hemen önce alınır. Animasyon pürüzsüz başlar.
⚠️ Dikkat Edilmesi Gerekenler
useLayoutEffectsenkron çalışır; yani React ekranı boyamadan önce burada bekler. Fazla veya ağır işlemler UI’ı dondurabilir.- SSR (Server Side Rendering) ortamında
useLayoutEffecthata verir, çünkü sunucuda “layout” yoktur.
import { useLayoutEffect, useEffect } from 'react';
const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
- Gereksiz
useLayoutEffectkullanımı performansı düşürür. Her şeyi senkron yapmak iyi değildir.
Performans ve React 18+
React 18 ile birlikte gelen Concurrent Rendering, useLayoutEffect gibi senkron efektleri daha iyi planlamaya başladı. Ancak yine de bloklayıcı işlemlerden kaçınmak gerekir.
💡 İpucu: Animasyonlarda requestAnimationFrame ile birlikte useLayoutEffect kullanmak en pürüzsüz sonucu verir.
Bonus: useInsertionEffect
React 18 ile gelen useInsertionEffect, useLayoutEffect’ten bile önce çalışır. Genellikle CSS-in-JS kütüphaneleri (ör. Emotion, Styled Components) tarafından stilleri DOM’a en erken aşamada eklemek için kullanılır.
Zamanlama sırası:
useInsertionEffect → useLayoutEffect → paint → useEffect
Gerçek Hayattan Örnek
Bir modal açıldığında arka planın bulanıklaşmasını istiyorsun. Bu işlemi useEffect ile yaparsan kullanıcı önce modal’ı görür, sonra arka plan kararıp bulanıklaşır. Ancak useLayoutEffect kullanırsan her şey aynı anda gerçekleşir — daha profesyonel bir deneyim. 💅
Sonuç
useEffect→ Kullanıcı UI’ı gördükten sonra arka plan işlemlerini yap.useLayoutEffect→ Kullanıcı görmeden DOM’u hazırla, ölç ve düzenle.
useEffect arka planda çalışır, useLayoutEffect sahneye çıkmadan perdeyi düzeltir. Doğru yerde doğru Hook’u kullanmak, performansı kadar algılanan kaliteyi de yükseltir. React’te zamanlama, UX’in görünmeyen kahramanıdır.