Debounce ve throttle, özellikle kullanıcı girdilerine (arama çubuğu, filtreleme) veya sürekli tetiklenen olaylara (scroll, resize) tepki verirken React uygulamalarının performansını optimize etmek için kritik tekniklerdir. İkisi de bir işlevin ne sıklıkta çağrılacağını kontrol eder, ancak farklı şekilde çalışır. Bu yazıda, her iki yöntemi detaylandıracak, React'te nasıl özel hook'lar oluşturulacağını gösterecek ve React useCallback ve useMemo ile render optimizasyonu gibi ileri tekniklerle nasıl entegre edileceğine değineceğiz.
Debounce Nedir ve Ne Zaman Kullanılır?
Debounce, bir işlevin belirli bir süre boyunca son çağrıldıktan sonra yalnızca bir kez çalışmasını sağlar. Yani, kullanıcı yazmayı bırakana kadar işlemi erteler. En yaygın kullanım alanı canlı arama kutusudur: Kullanıcı her harf yazdığında API çağrısı yapmak yerine, yazmayı durdurduktan sonra tek bir çağrı yapılır. Bu, gereksiz ağ isteklerini ve sunucu yükünü azaltır.
Örneğin, bir arama bileşeninde her tuş vuruşunda arama sonuçları getiren bir API çağrısı yapmak kaynak israfına yol açar. Debounce ile 300ms gibi bir gecikme ekleyerek yalnızca kullanıcı durakladığında istek gönderirsiniz.
Throttle Nedir ve Ne Zaman Kullanılır?
Throttle ise bir işlevin belirli bir zaman aralığında en fazla bir kez çalışmasını garanti eder. Scroll olayları, pencere yeniden boyutlandırma veya oyunlardaki sürekli tuş basımları için idealdir. Scroll pozisyonunu takip ederken throttle kullanarak kaydırma hızından bağımsız olarak düzenli aralıklarla işlem yapabilirsiniz.
Debounce ve Throttle Arasındaki Farklar
| Özellik | Debounce | Throttle |
|---|---|---|
| Çalışma mantığı | Son çağrıdan sonra gecikme süresi dolunca çalışır. | Belirli aralıklarla düzenli olarak çalışır. |
| Kullanım senaryoları | Otomatik tamamlama, arama, form doğrulama. | Scroll, resize, mouse hareketleri, oyun. |
| İlk çağrı | Gecikme süresi kadar ertelenir. | İlk çağrı anında çalışır, sonra aralıklarla. |
| Son çağrı | Son çağrıdan sonra gecikme süresi kadar çalışmaz. | Son çağrıdan sonra aralık süresi dolana kadar çalışmaz. |
React'te Custom Hook ile Debounce Uygulaması
React'te debounce işlevselliğini kolayca yeniden kullanmak için özel bir hook oluşturabiliriz. Aşağıdaki useDebounce hook'u, bir değeri belirtilen gecikme süresi boyunca debounce eder:
import { useState, useEffect } from 'react';
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}Bu hook, value değiştiğinde belirtilen delay kadar bekler ve son değeri günceller. Kullanımı oldukça basittir:
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 300);
// debouncedSearchTerm değiştiğinde API çağrısı yap
useEffect(() => {
if (debouncedSearchTerm) {
fetchResults(debouncedSearchTerm);
}
}, [debouncedSearchTerm]);Bu sayede API çağrıları kullanıcı yazmayı bırakana kadar bekletilir. Performans artışını hemen fark edeceksiniz.
React'te Custom Hook ile Throttle Uygulaması
Throttle için de benzer bir hook yazabiliriz. Ancak throttle, ilk çağrıyı hemen yapmalı ve sonra aralıklarla tekrarlamalıdır. Aşağıdaki useThrottle hook'u bu işlevi sağlar:
import { useState, useEffect, useRef } from 'react';
function useThrottle(value, interval) {
const [throttledValue, setThrottledValue] = useState(value);
const lastExecuted = useRef(Date.now());
useEffect(() => {
const now = Date.now();
if (now - lastExecuted.current >= interval) {
setThrottledValue(value);
lastExecuted.current = now;
} else {
const timerId = setTimeout(() => {
setThrottledValue(value);
lastExecuted.current = Date.now();
}, interval - (now - lastExecuted.current));
return () => clearTimeout(timerId);
}
}, [value, interval]);
return throttledValue;
}Bu hook, value değiştiğinde hemen değilse, son çalıştırmadan itibaren interval kadar zaman geçmişse hemen günceller, aksi halde kalan süre kadar bekler. Scroll pozisyonu takibi için idealdir:
const [scrollY, setScrollY] = useState(0);
const throttledScrollY = useThrottle(scrollY, 100);
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY);
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);Yaygın Hatalar ve Dikkat Edilmesi Gerekenler
Debounce ve throttle uygularken dikkat edilmesi gereken bazı noktalar vardır:
- Bellek sızıntıları: useDebounce hook'unda useEffect temizleme fonksiyonunda setTimeout'u temizlediğinizden emin olun. Aksi halde bileşen unmount olduktan sonra setState çağrılabilir.
- Yanlış bağımlılıklar: useEffect'in bağımlılık dizisine
valuevedelayeklemeyi unutmayın. Eksik bağımlılıklar eski değerlere takılmanıza neden olur. - useCallback ve useMemo ile birlikte kullanım: Eğer debounce işlevi bir bileşene prop olarak geçiyorsa,
useCallbackile sarmalayarak gereksiz yeniden oluşturmayı önleyin. Bu konuda daha fazla bilgi için React useCallback ve useMemo ile Render Optimizasyonu yazımıza göz atabilirsiniz. - Throttle'da ilk çağrı: Bazı throttle implementasyonlarında ilk çağrı hemen yapılmaz; bu kullanıcı deneyimini olumsuz etkileyebilir. Hook'umuz ilk çağrıyı hemen yapacak şekilde tasarlandı.
Örneğin, arama önerileri gibi bir özellik geliştirirken debounce eklemek, kullanıcının her tuşa basışında API'ye istek gitmesini engelleyerek hem sunucu hem de istemci tarafında kayda değer bir performans kazancı sağlar. Benzer şekilde, scroll tabanlı animasyonlar veya sonsuz kaydırma (infinite scroll) uygulamalarında throttle kullanmak, tarayıcının gereksiz hesaplamalar yapmasını önler.
Bir başka yaygın hata, debounce süresini çok kısa (örneğin 50ms) veya çok uzun (örneğin 1 saniye) ayarlamaktır. Genel bir kural olarak, arama için 300-500ms, scroll için 100-200ms uygundur. Ancak bu değerler uygulamanıza bağlı olarak değişebilir; test ederek optimum süreyi bulun.
Custom hook'lar, bu mantığı projenizin farklı bölümlerinde tekrar tekrar kullanmanızı sağlar. Debounce ve throttle hook'larınızı ayrı bir dosyada tutun ve ihtiyaç duyduğunuz her yerde import edin. Bu, kodunuzu daha modüler ve bakımı kolay hale getirir.
Son olarak, React Native uygulamalarında deep linking gibi farklı bağlamlarda da bu tekniklerin kullanılabileceğini unutmayın. Web ve mobil geliştirmede performans optimizasyonu her zaman öncelikli olmalıdır.
Bu rehberde debounce ve throttle'ın ne olduğunu, aralarındaki farkları ve React'te custom hook'lar ile nasıl uygulanacağını öğrendiniz. Şimdi bu bilgileri kendi projelerinizde kullanarak kullanıcı deneyimini iyileştirebilirsiniz. Unutmayın: Doğru teknik, doğru yerde kullanıldığında gerçekten değer katar.
Sık Sorulan Sorular
Debounce ile throttle arasındaki temel fark nedir?
Debounce, bir işlevi son çağrıdan sonra belirtilen süre boyunca bekletip tek bir kez çalıştırırken; throttle, işlevi belirli aralıklarla düzenli olarak çalıştırır. Debounce genellikle arama kutusu gibi kullanıcının duraklamasını bekleyen durumlar için, throttle ise scroll gibi sürekli tetiklenen olaylar için uygundur.
React'te debounce hook'u nasıl oluşturulur?
useState ve useEffect kullanarak bir değeri belirtilen gecikme süresi kadar bekletip güncelleyen bir özel hook yazabilirsiniz. setTimeout ile gecikme ayarlanır ve temizleme fonksiyonunda clearTimeout ile bellek sızıntısı önlenir.
Throttle hook'u ilk çağrıyı hemen yapıyor mu?
Yukarıdaki useThrottle implementasyonu, ilk çağrıyı hemen yapar ve ardından belirtilen interval kadar bekler. Bu, kullanıcı deneyimi açısından önemlidir. Ancak bazı implementasyonlarda ilk çağrı da ertelenebilir.
Debounce süresini ne olarak ayarlamalıyım?
Kullanım senaryosuna bağlıdır. Arama kutuları için genellikle 300-500ms, scroll olayları için 100-200ms uygundur. Uygulamanızın ihtiyaçlarına göre test ederek optimum değeri bulmalısınız.






