Çoğu zaman bir React geliştiricisi olarak uygulamanın optimizasyonuna ve performans iyileştirmelerine odaklanmamız gerekir. Üçüncü taraf araçlardan yerel özelliklere kadar çok hızlı bir React uygulama performansını arşivlemenin birden çok yolu vardır.
Konuya başlamadan önce Memoization nedir onun hakkında küçük bir bilgi paylaşmak istiyorum.
Memoization bir yapı değil, bir optimizasyon tekniğidir. En basit anlatımıyla memory kullanımı çok fazla olan yani maliyeti çok fazla olan dataların cachlenerek hafızada tutulması tekniğidir.Bu sayede pahalı işlemi tekrar yapmadan cacheten çağırarak bize daha iyi performans sağlayan bir yöntemdir uygulamamızın performansını arttıran bir yöntemdir.
React Memo nedir ?
React Memo bir Higher Order Component (HOC)’dir. Basitçe bileşenin etrafını saran işlenen çıktıyı hafızada tutan ve gereksiz işlemeleri atlayan bir yapı diyebiliriz. Bunu yaparken component içinde bulunan yada dışarıdan gelen data ile ilgilenir. Ayrıca React Memo, bileşenin, değerin değişip değişmediğini görmek için eski prop ile yeni propsun karşılaştırmasına izin verir. Eğer proplarda hiçbir değişiklik yoksa ,React onu oluşturmayı atlar ve en son oluşturulan sonucu yeniden kullanır. React Memo sadece proplar üzerinden değil oluşturduğunuz component eğer hooklar kullanıyorsa ve buralarda bir değişim söz konusu ise örnek olarak useState
durumu useReducer
veya useContext
içeriği değiştiğinde yine de yeniden oluşturulacaktır.
React Memo nerede kullanılır?
Bu yöntemin sadece bir performans optimizasyonu olarak var olduğunu önceden bilmeliyiz .Bunları nerede kullanacağınız konusunda dikkat etmeniz gereken bazı önemli noktalara şunları örnek olarak verebiliriz:
Eğer pure functional component kullanıyorsanız
Bir bileşenin oldukça sık render olacağını önceden bildiğinizde kullanın
Şİmdi bu sık render olma özelliğine basit bir örnek ile yaklaşalım.
Basitçe Youtube uygulamasını hayal edelim ve örnek olarak elmizde söyle bir comp .olsun.
function VideoDescription({ title, user, viewCount }) {
return (
<div>
<Description title={title} user={user}/>TotalViews: {viewCount}
</div>
);
}
Şuna dikkat etmeniz istiyorum.
Burada biz functional component kullandık class component değil !
Componentimiz props olarak 3 değer alır bunlar title,user ve viewCount.
Şimdi bunu uygulamamızda ekrana bastırmak istediğimiz zaman ne olur ?
<VideoDescription viewCount={0} title="My Song" user="Amy Lee" />
Şimdi burada normal şartlarda viewCount değerimizi bir bir arttırısak ne olur ? VideoDescription componentimiz otomatik olarak yeniden render olur değil mi ? Bunun sebebi içeride olan değişiklik yani bizim viewCount değerimizi arttırmamız. Bu verdiğimiz örnek çok basit bu şekilde milyonlarca Description işlemini ekrana bastığımızı düşündüğünüz ve real-time olarak sonuçların durmadan değiştiğini düşündüğümüz zaman durmadan render olan bir VideoDescription componenti elde etmiş olacağız. Bu uygulamamızın performansını oldukça kötü etkiler Bu nedenle, burada, alt Description
bileşenine memoization uygulamak için mükemmel bir durum elde ediyoruz.
Şimdi daha anlaşılır olması için beraber bir uygulama geliştirelim ve onun üzerinde kontrol edelim bu durumu. Şimdi bir Todo uygulaması yapalım.
Öncelikle bir React Projesi oluşturalım ve App.js içine girerek uygulamamızı geliştirmeye başlayalım.
2 adet state ekleyelim .
Birisi listeyi tutmak için todo statetimiz.
İkincisi ise Inputtan gelen textleri tutmamız için bir text state.
Daha sonra değerleri almamız ve listeye eklemizde yardımcı olması için bir adet input ve bir adet button ekleyelim uygulamamıza daha sonra Tüm bu elemanları listeyen bir Todo isminde componentimiz olsun.
Todo componentimiz ise tüm bu listeyi sarmalayan bir yapı.
TodoItem iste tek bir liste elemanı.
Şimdi projemizi run alalım ve ekrana çözüken sonuca hep beraber bakalım.
Gördüğünüz gibi sadece iki adet defauld olarak eklediğimiz liste elemanı gözüküyor Şimdi hep beraber kritik noktalara bakalım..
Geliştirici konsolumuzu açalım.
Gördüğünüz gibi öncelikle bir kere App çalıştı daha sonra Todo bir kere çalıştı ve liste içinde iki item olduğu için iki kere TodoItem çalıştı.
Şimdi bir adet todo listesine eleman ekleyelim ve sonucu görelim.
Ben sonuçlar arasında ayrımlar yapabilmemiz için App içine bir adet
console.log("*******************************") yazdım
Input alanına tıkladıktan sonra klavyeden sadece 1 kere M harfine basalım ve olanları beraber görelim.
Gördüğünüz gibi tekrar render oldu alan.
Şimdi Tekrar ınput alanında E harfine basalım.
Fark ettiğiniz üzere klavyede ınput alanına her ekleme yaptığımız zaman tekrar tekrar render component bunun sebebi text state elemanımızın değişmesi.
Şimdi App compenetimizde olan bir değişim yüzünden neden alt kısımlar etkilensin sadece kendisi etkilensin istiyoruz biz neden child componentler yeniden render olup uygulamızı yavaşlatsın bunun önüne geçmek için öncelikle child componentimize use memo yapısını uygulayalım.
Uygulamanızda React Memo’yu kullanın
Artık React Memo hakkında her şeyi bildiğinize göre, onu gerçekten kullanan bir React componenti nasıl oluşturabiliriz ona bakalım.
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
Yukarıda nasıl React.Memo kullanılır basit bir örneğini gösteriliyor. Şimdi bunu kendi uygulamızda Todo için uygulayalım.
Todo compenetimizi şekildeki gibi güncelleyelim.
Tarayıcımızı yada consolumuzu yenileyelim ve yeni bom bom bir konsol ile sonuca tekrar bakalım.
Şimdi tekrar ınput alanımıza tıklayalım ve M harfine basalım.
Gördüğünüz gibi sadece App yeniden oluşturuldu içerik değişmedi.
E harfine basalım ve tekrar kontrol edelim. Sadece App re-render oldu.
Şimdi sadece bu durumda App içinde olan değişikliklerden sadece App in render olmasını sağladık peki Todo içinde bir değişiklik olursa ne olacak ?
Bunun için Todo’ya yukarıda yazdığımı “eM” kelimesini ekleyelim.
Şimdi bir uygulama geliştirdiğimizi düşünelim içinde milyonlarca data var ve bu datayı ekranda listeleyip ekranda o data için değişimler ekleme çıkarma gibi işlemler yaptığımızı düşünelim. Hatta düşünmeden örnek ile beraber çalışalım.
Yukarıda fark edeceğiniz üzere App render oluyor daha sonra Todo içinde bir değişiklik olursa Todo çalışıyor buraya kadar herşey normal değil mi ? Şunu gözden kaçırmayalım Todo yeniden re-render olunca Todo içinde bulunan her bir TodoItem yeniden oluşturuluyor. Şimdi 1.000.000 tane elemanımız olduğunu düşünelim 1.000.001. elemanı listeye eklediğimiz zaman üstte bulunan1.000.000 eleman tekrar render olacak performansı nasıl etkiler hayal edebildiniz mi ?
Bunu engellemek içinde en basit işlem React.Memo() kullanmak. Şimdi biz yeni eklenen her bir elemandan öncesini memory içinde tutmak Bunun için TodoItem comp. güncelleyelim.
Şimdi Konsolumuzu temizleyelim ve listemize yeni birkaç item ekleyelim.
Gördüğünüz gibi sadece o eklenen eleman render oldu geri kalanlar render olmadı .
İşte React.Memo() bu kadar kolay :)
Umarım yararlı olmuştur teşekkür ederim.