Cansu Arı Logo
Blog
Nedir?

useEffect mi, useLayoutEffect mi? Milisaniyelerin Savaşı

Fark sadece zamanlama değil; kullanıcı deneyimi, performans ve görsel akıcılık açısından kritik bir detay.

  • #React
  • #Performans

Skip to content

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ı
useLayoutEffectDOM güncellendikten hemen sonra, ekran çizilmeden önceDOM ölçümleri, senkron düzenlemeler, animasyon başlangıçları
useEffectTarayıcı çizimi tamamlandıktan sonraVeri çekme, event listener ekleme, state kaydetme
Özetle: 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:

  1. Render aşaması: React bileşenleri sanal DOM’a yazar.
  2. Commit aşaması: Gerçek DOM güncellenir.
  3. Layout Effect aşaması: useLayoutEffect devreye girer — DOM güncel ama henüz ekrana çizilmemiştir.
  4. Paint aşaması: Tarayıcı ekrana yeni görünümü çizer.
  5. Effect aşaması: useEffect çalışır — kullanıcı yeni görünümü artık görmektedir.
Bu akış, özellikle ölçüm ve animasyon işlemlerinde zamanlamayı belirler.

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ı?

SenaryoDoğru Hook
API’den veri çekmekuseEffect
Event listener ekleme / kaldırmauseEffect
localStorage veya analytics işlemleriuseEffect
DOM ölçümü veya manipülasyonuuseLayoutEffect
Tooltip / modal konumlandırmauseLayoutEffect
CSS animasyonu başlatmauseLayoutEffect
Görsel hizalama düzeltmesiuseLayoutEffect
Kural: Eğer DOM’a erişmen veya pozisyon, ölçüm, hizalama yapman gerekiyorsa 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

  • useLayoutEffect senkron çalışır; yani React ekranı boyamadan önce burada bekler. Fazla veya ağır işlemler UI’ı dondurabilir.
  • SSR (Server Side Rendering) ortamında useLayoutEffect hata verir, çünkü sunucuda “layout” yoktur.
Çözüm:
import { useLayoutEffect, useEffect } from 'react';
const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
  • Gereksiz useLayoutEffect kullanı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ı:

useInsertionEffectuseLayoutEffect → 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.
Kısacası: 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.
All tags
  • React
  • Performans