React'ta Performans Optimizasyon Kancası useMemo
İnceleyeceğimiz ilk performans optimizasyon
kancası - useMemo.
Bu kancası, ekranın yeniden çizilmesi anları arasında kaynak yoğun işlemlerin sonuçlarını önbelleğe almanıza yardımcı olur ve böylece gereksiz hacimli hesaplamalardan kaçınabilir. Bu tür önbelleğe alma işlemine memorizasyon da denir.
Bunun nasıl çalıştığına bakalım. Bir düğme ve
h3 başlığı olan bir bileşen oluşturalım:
return (
<div>
<h3>Metin</h3>
<button>tıkla</button>
</div>
);
Şimdi, başlığa tıklandığında renginin turuncudan
yeşile ve tersi yönde değişmesini sağlayalım. Öncelikle
bir isGreen state'i oluşturalım:
const [isGreen, setIsGreen] = useState(false);
Başlığın style niteliğine rengi değiştirme
koşulunu ekleyelim ve bir tıklama işleyicisi ekleyelim:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Metin</h3>
Ayrıca, düğmemize her tıklandığında bir artan herhangi bir değerimiz de olsun. Bunun için bir state oluşturalım:
const [num, setNum] = useState(0);
Düğmeye tıklama işlemini ekleyelim:
<button onClick={() => setNum(num + 1)}>
tıklamalar
</button>
Ayrıca, num değerinin karesini döndüren
square adında bir fonksiyonumuz olsun.
Fonksiyonun çağrı sonucunu result
değişkenine yazacağız:
const result = square(num);
function square(num) {
return num * num;
}
result'u düğmenin metninde gösterelim:
<button onClick={() => setNum(num + 1)}>
tıklamalar: {result}
</button>
Sonuç olarak şunu elde ettik: düğmeye tıklandığında
num değeri değişir, ardından karesi alınır,
ve başlığa tıklandığında başlığın rengi değişir.
Çok küçük bir bileşenimiz var, başlığa tıklandığında rengini değiştirmek için tüm bileşen yeniden çizilmesine rağmen her şey hızlı çalışıyor, buna bağlı olarak düğmeye bağlı hesaplamalar da yeniden yapılıyor, bu ona dokunmamıza rağmen. Peki ya hesaplamalarımız hacimli olsaydı ve her seferinde her şey yeniden hesaplansaydı?
Fonksiyonumuzu biraz ağırlaştıralım, şimdi biraz daha uzun süre düşünecek. Böylece uzun hesaplamaları simüle etmiş olacağız:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Sadece hiçbir şey yapma ...
}
return num * num;
}
Şimdi başlığa tıklayın. Görülüyor ki, square
fonksiyonunun uzun süren çalışması nedeniyle (oysa
düğmeye dokunmuyoruz) başlığın renginin değişmesi
için sonsuza kadar beklemek zorundayız!
İşte burada useMemo kancası yardımımıza
koşuyor. Bunun için, ilk parametre olarak önbelleğe
almak istediğimiz değeri hesaplayan bir fonksiyon
iletmeliyiz, bu fonksiyon saf olmalı ve herhangi bir
parametre almamalıdır. İkinci parametre olarak ise
köşeli parantezler içinde bağımlılıkları, başka bir
deyişle, fonksiyon kodunda yer alan tüm reaktif
değerleri. Böylece, result içine şu yapıyı
yazacağız:
const result = useMemo(() => square(num), [num]);
Tekrar başlığa tıklayalım. Şimdi, eğer hesaplamalı
düğmeye dokunmazsak ve böylece num state
değerini değiştirmezsek, hiçbir şey yeniden
hesaplanmaz ve React düğmede önbelleğe alınmış
değeri gösterir, bu yüzden başlığımız rengini
hızla değiştirir.
Bir App bileşeni oluşturun, içine bir
paragraf yerleştirin. Başlangıç değeri
'react' olan bir text state'i
oluşturun, state değeri paragraf metni olarak
görüntülensin. Paragrafa tıklandığında, metnin
sonuna bir ünlem işareti eklensin.
Başlangıç değeri 0 olan bir num
state'i daha oluşturun. App içine bir
paragraf daha yerleştirin. Üzerine tıklandığında
num değerinin 1 arttığından emin olun.
Şimdi App'ye, parametre olarak num'u
alan ve üç katını döndüren triple adında bir
fonksiyon ekleyin. Fonksiyonun çağrı sonucunu
result değişkenine atayın. result'u
ikinci paragrafın metni olarak görüntüleyin.
Paragraflara sırayla tıklayın, ünlem işaretlerinin
ne kadar yavaş eklendiğini gözlemleyin.
Yavaş çalışan triple fonksiyonunu
useMemo ile sararak durumu düzeltin.