Memoization, önbelleğe almaya benzer bir optimizasyon tekniğidir. Bir işlev çağrısının önceki sonuçlarını depolayarak ve işlevin bir sonraki çalışmasında bu sonuçları kullanarak çalışır. Aynı parametrelerde işlev çağrılarını tekrarlayan hesaplama ağırlıklı uygulamalarda özellikle yararlıdır.

Not almayı düz JavaScript'te ve ayrıca React'te birkaç farklı şekilde kullanabilirsiniz.

JavaScript'te not alma

JavaScript'te bir işlevi not almak için, o işlevin sonuçlarını bir önbellekte saklamanız gerekir. Önbellek, bağımsız değişkenlerin anahtar ve sonuçların değer olduğu bir nesne olabilir.

Bu işlevi çağırdığınızda, çalıştırmadan önce sonucun önbellekte olup olmadığını kontrol eder. Eğer öyleyse, önbelleğe alınmış sonuçları döndürür. Aksi takdirde yürütülür.

Bu işlevi düşünün:

işlevMeydan(sayı) {
dönüş sayı * sayı
}

İşlev bir argüman alır ve karesini döndürür.

Fonksiyonu çalıştırmak için aşağıdaki gibi bir numara ile çağırın:

Meydan(5) // 25

Argüman olarak 5 ile square() oldukça hızlı çalışacaktır. Ancak 70.000'in karesini hesaplayacak olursanız, gözle görülür bir gecikme olacaktır. Çok fazla değil ama yine de bir gecikme. Şimdi, işlevi birden çok kez çağırır ve 70.000'i geçerseniz, her aramada bir gecikme yaşarsınız.

instagram viewer

Memoization kullanarak bu gecikmeyi ortadan kaldırabilirsiniz.

const memoizedSquare = () => {
İzin Vermek önbellek = {};
dönüş (sayı) => {
if (sayı önbellek) {
konsol.log('Önbelleğe alınmış değeri yeniden kullanma');
dönüş önbellek[sayı];
} başka {
konsol.log('Hesaplama sonucu');
İzin Vermek sonuç = sayı * sayı;

// önbellek en yenisonuçdeğeriçinsonrakizaman
önbellek[sayı] = sonuç;
dönüş sonuç;
}
}
}

Bu örnekte, işlev, sonucun önbellek nesnesinde bulunup bulunmadığını kontrol ederek daha önce hesaplanıp hesaplanmadığını kontrol eder. Varsa, önceden hesaplanmış değeri döndürür.

İşlev yeni bir sayı aldığında, yeni bir değer hesaplar ve sonuçları dönmeden önce önbellekte saklar.

Yine bu örnek oldukça basittir, ancak bir programın performansını iyileştirmek için not almanın nasıl çalışacağını açıklar.

Yalnızca saf işlevleri not almalısınız. Bu işlevler, aynı argümanları ilettiğinizde aynı sonucu döndürür. Saf olmayan işlevlerde not almayı kullanırsanız, performansı iyileştirmezsiniz, ancak ek yükünüzü artırırsınız. Bunun nedeni, bir işlevi her not ettiğinizde bellek yerine hızı seçmenizdir.

React'te not alma

React bileşenlerini optimize etmek istiyorsanız, React useMemo() kancası, React.memo ve useCallBack() aracılığıyla notlandırma sağlar.

useMemo()'yu kullanma

useMemo() bir Tepki kancası bir işlevi ve bir bağımlılık dizisini kabul eden.

const memoizedValue = useMemo(() => hesaplamaExpensiveValue (a, b), [a, b]);

Bu fonksiyondan döndürülen değeri hafızaya alır. Bağımlılık dizisindeki değerler, işlevin ne zaman yürütüldüğünü belirler. Yalnızca değiştiklerinde işlev yeniden yürütülür.

Örneğin, aşağıdaki Uygulama bileşeninin sonuç olarak adlandırılan, not alınmış bir değeri vardır.

içe aktarmak { kullanım notu } itibaren "tepki"
işlevUygulama(değer) {
const kare = (değer) => {
dönüş değer * değer
}
const sonuç = kullanMemo(
() => kare (değer),
[ değer ]
);
dönüş (
<div>{sonuç (5)}</div>
)
}

Uygulama bileşeni, her işlemede square() öğesini çağırır. Uygulama bileşeni, aşağıdakilerden dolayı birçok kez oluşturulursa performans düşecektir. Tepki sahne değiştirme veya durum güncelleme, özellikle de square() işlevi pahalıysa.

Ancak, useMemo() döndürülen değerleri önbelleğe aldığından, bağımlılık dizisindeki bağımsız değişkenler değişmedikçe kare işlevi her yeniden işlemede yürütülmez.

React.memo()'yu kullanma

React.memo(), bir React bileşenini ve bir işlevi bağımsız değişken olarak kabul eden daha yüksek dereceli bir bileşendir. İşlev, bileşenin ne zaman güncellenmesi gerektiğini belirler.

Bu işlev isteğe bağlıdır ve sağlanmadıysa, React.memo, bileşenin mevcut prop'larını önceki props'larla sığ bir kopya karşılaştırması yapar. Sahne öğeleri farklıysa, bir güncellemeyi tetikler. Sahne öğeleri aynıysa, yeniden oluşturmayı atlar ve hafızaya alınan değerleri yeniden kullanır.

İsteğe bağlı işlev, önceki props ve sonraki props'ları argüman olarak kabul eder. Ardından, bileşeni güncelleyip güncellememeye karar vermek için bu aksesuarları açıkça karşılaştırabilirsiniz.

Tepki.hafıza(Bileşen, [areEqual (prevProps, nextProps)])

Önce isteğe bağlı işlev argümanı olmayan bir örneğe bakalım. Aşağıda, adı ve e-posta özelliklerini kabul eden Yorumlar adlı bir bileşen bulunmaktadır.

işlevYorumlar ({isim, yorum, beğeniler}) {
dönüş (
<div>
<p>{isim}</p>
<p>{yorum}</p>
<p>{seviyor}</p>
</div>
)
}

Not alınan yorumlar bileşeni, etrafına şu şekilde sarılmış React.memo'ya sahip olacaktır:

const MemoizedComment = React.memo (Yorum)

Arayabilir ve diğer React bileşenleri gibi çağırabilirsiniz.

<MemoizedYorum adı="Mary" yorum="Not alma harika" beğeni=1/>

Sahne karşılaştırmasını kendiniz yapmak istiyorsanız, aşağıdaki işlevi ikinci argüman olarak React.memo'ya iletin.

içe aktarmak Tepki itibaren "tepki"
işlevkontrolYorumProps(prevProps, nextProps) {
dönüş prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}

const MemoizedComment = React.memo (Yorumlar, checkCommentProps)

checkProfileProps true değerini döndürürse, bileşen güncellenmez. Aksi takdirde, yeniden oluşturulur.

Özel işlev, yeniden oluşturmayı özelleştirmek istediğinizde kullanışlıdır. Örneğin, bunu yalnızca beğeni sayısı değiştiğinde Yorumlar bileşenini güncellemek için kullanabilirsiniz.

Yalnızca bir işlevin döndürülen değerini not alan useMemo() kancasının aksine, React.memo tüm işlevi not alır.

React.memo'yu yalnızca saf bileşenler için kullanın. Ayrıca, karşılaştırma maliyetlerini azaltmak için, yalnızca donanımları sık sık değişen bileşenleri not alın.

useCallBack()'i kullanma

Not almak için useCallBack() kancasını kullanabilirsiniz. fonksiyon bileşenleri.

const memoizedCallback = useCallback(
() => {
doSomething (a, b);
},
[a, b],
);

İşlev, yalnızca bağımlılık dizisindeki değerler değiştiğinde güncellenir. Kanca, useMemo() geri çağrısı gibi çalışır, ancak işlev bileşenini, değerleri not almak yerine işlemeler arasında not alır.

Bir API çağıran, not alınmış bir işleve ilişkin aşağıdaki örneği düşünün.

içe aktarmak { useCallback, useEffect } itibaren "tepki";
const Bileşen = () => {
const getData = useCallback(() => {
konsol.log('bir API çağır');
}, []);
useEffect(() => {
getData();
}, [getData]);
};

useEffect içinde çağrılan getData() işlevi, yalnızca getData değeri değiştiğinde yeniden çağrılır.

Not Almalı Mısınız?

Bu eğitimde, memoization'ın ne olduğunu, faydalarını ve JavaScript ile React'te nasıl uygulanacağını öğrendiniz. Ancak, React'in zaten hızlı olduğunu bilmelisiniz. Çoğu durumda, bileşenleri veya değerleri not almak, karşılaştırma maliyetleri ekler ve performansı iyileştirmez. Bu nedenle, yalnızca pahalı bileşenleri not edin.

React 18 ayrıca useId, useTransition ve useInsertionEffect gibi yeni kancaları da tanıttı. Bunları, React uygulamalarının performansını ve kullanıcı deneyimini geliştirmek için kullanabilirsiniz.