React Uygulamalarında Performansı İyileştirme ve Optimize Etme Yöntemleri

Yayınlanan: 2022-03-10
Kısa özet ↬ React tanıtıldığından beri, ön uç geliştiricilerin web uygulamaları oluşturma şeklini değiştirdi ve sanal DOM'si bileşenleri etkin bir şekilde oluşturmasıyla ünlüdür. Bu eğitimde, React uygulamalarında performansı optimize etmenin çeşitli yöntemlerini ve ayrıca React'in performansı iyileştirmek için kullanabileceğimiz özelliklerini tartışacağız.

React, web uygulamalarının kullanıcı arayüzlerini (UI'ler) hızlı bir şekilde güncellemesini sağlar, ancak bu, orta veya büyük React uygulamanızın verimli bir şekilde çalışacağı anlamına gelmez. Performansı, React'i oluştururken nasıl kullandığınıza ve React'in nasıl çalıştığına ve bileşenlerin yaşam döngülerinin çeşitli aşamalarında yaşadığı sürece ilişkin anlayışınıza bağlı olacaktır. React, bir web uygulamasına birçok performans iyileştirmesi sunar ve bu iyileştirmeleri çeşitli teknikler, özellikler ve araçlar aracılığıyla gerçekleştirebilirsiniz.

Bu eğitimde, React uygulamalarında performansı optimize etmenin çeşitli yöntemlerini ve ayrıca React'in performansı iyileştirmek için kullanabileceğimiz özelliklerini tartışacağız.

Bir React Uygulamasında Performansı Optimize Etmeye Nereden Başlanmalı?

Tam olarak ne zaman ve nerede optimize edeceğimizi bilmeden bir uygulamayı optimize etmeye başlayamayız. “Nereden başlıyoruz?” diye soruyor olabilirsiniz.

İlk oluşturma işlemi sırasında React, bileşenlerin bir DOM ağacını oluşturur. Bu nedenle, DOM ağacındaki veriler değiştiğinde, React'in ağaçta etkilenmeyen diğer bileşenleri atlayarak yalnızca değişiklikten etkilenen bileşenleri yeniden oluşturmasını istiyoruz.

Bununla birlikte, React, tümü etkilenmese bile DOM ağacındaki tüm bileşenleri yeniden oluşturmaya başlayabilir. Bu, daha uzun yükleme süresine, zaman kaybına ve hatta CPU kaynaklarının boşa harcanmasına neden olur. Bunun olmasını önlememiz gerekiyor. Dolayısıyla, optimizasyon çabamıza odaklanacağımız yer burasıdır.

Bu durumda, kaynak ve zaman israfını önlemek için her bileşeni yalnızca gerektiğinde oluşturacak veya farklılaştıracak şekilde yapılandırabiliriz.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Performans ölçülüyor

React uygulamanızın optimizasyon sürecini asla hissettiklerinize göre başlatmayın. Bunun yerine, React uygulamanızın performansını analiz etmek için mevcut ölçüm araçlarını kullanın ve onu neyin yavaşlatabileceğine dair ayrıntılı bir rapor alın.

Chrome'un Performans Sekmesi ile React Bileşenlerini Analiz Etme

React'in belgelerine göre, hala geliştirme modundayken, React bileşenlerinin nasıl monte edildiğini, güncellendiğini ve bağlantısını kestiğini görselleştirmek için Chrome tarayıcısındaki "Performans" sekmesini kullanabilirsiniz. Örneğin, aşağıdaki resim Chrome'un "Performans" sekmesini gösterir ve blogumu geliştirme modunda analiz eder.

Performans profili oluşturucu özeti
Performans profili oluşturucu özeti (Geniş önizleme)

Bunu yapmak için şu adımları izleyin:

  1. Tüm uzantıları, özellikle React Developer Tools'u geçici olarak devre dışı bırakın, çünkü bunlar analizin sonucunu bozabilirler. Tarayıcınızı gizli modda çalıştırarak uzantıları kolayca devre dışı bırakabilirsiniz.
  2. Uygulamanın geliştirme modunda çalıştığından emin olun. Diğer bir deyişle, uygulama yerel ana makinenizde çalışıyor olmalıdır.
  3. Chrome'un Geliştirici Araçlarını açın, “Performans” sekmesine tıklayın ve ardından “Kaydet” düğmesine tıklayın.
  4. Profillemek istediğiniz eylemleri gerçekleştirin. 20 saniyeden fazla kayıt yapmayın, aksi takdirde Chrome askıda kalabilir.
  5. Kaydı durdurun.
  6. React olayları “User Timing” etiketi altında gruplandırılacaktır.

Profil oluşturucudan gelen sayılar görecelidir. Çoğu zaman ve bileşenler üretimde daha hızlı işlenir. Yine de bu, kullanıcı arayüzünün yanlışlıkla ne zaman güncellendiğini ve ayrıca kullanıcı arayüzü güncellemelerinin ne kadar derin ve ne sıklıkta gerçekleştiğini anlamanıza yardımcı olacaktır.

React Developer Tools Profiler

React'in belgelerine göre, react-dom 16.5+ ve react-native 0.57+ sürümlerinde, React Developer Tools Profiler kullanılarak geliştirici modunda gelişmiş profil oluşturma yetenekleri mevcuttur. Profil oluşturucu, bir React uygulamasındaki performans darboğazlarını belirlemek için oluşturulan her bileşen hakkında zamanlama bilgilerini harmanlamak için React'in deneysel Profiler API'sini kullanır.

Tarayıcınız için React Developer Tools'u indirmeniz yeterlidir, ardından onunla birlikte gelen profil oluşturma aracını kullanabilirsiniz. Profil oluşturucu yalnızca geliştirme modunda veya React v16.5+'ın üretim profili oluşturma yapısında kullanılabilir. Aşağıdaki resim, React Developer Tools Profiler kullanarak geliştirme modundaki blogumun profil oluşturucu özetidir:

React Developer Tools Profiler alev grafiği
React Developer Tools Profiler alev grafiği (Geniş önizleme)

Bunu başarmak için şu adımları izleyin:

  1. React Developer Tools'u indirin.
  2. React uygulamanızın geliştirme modunda veya React v16.5+'ın üretim profili oluşturma yapısında olduğundan emin olun.
  3. Chrome'un "Geliştirici Araçları" sekmesini açın. React Developer Tools tarafından sağlanan “Profiler” adlı yeni bir sekme mevcut olacak.
  4. “Kaydet” düğmesine tıklayın ve profil oluşturmak istediğiniz işlemleri gerçekleştirin. İdeal olarak, profil oluşturmak istediğiniz eylemleri gerçekleştirdikten sonra kaydı durdurun.
  5. React uygulamanızın tüm olay işleyicileri ve bileşenleriyle birlikte bir grafik (flamegraf olarak bilinir) görünecektir.

Not : Daha fazla bilgi için belgelere bakın.

React.memo React.memo() ile Not Alma

React v16, React.memo() adlı daha yüksek dereceli bir bileşen olan ek bir API ile piyasaya sürüldü. Belgelere göre, bu yalnızca bir performans optimizasyonu olarak mevcuttur.

Adı, " not ", temelde pahalı işlev çağrılarının sonuçlarını depolayarak ve aynı pahalı işlev yeniden çağrıldığında depolanan sonucu döndürerek esas olarak kodu hızlandırmak için kullanılan bir optimizasyon biçimi olan notlandırmadan gelir.

Memoization, bir işlevi bir kez, genellikle saf bir işlevi yürütmek ve ardından sonucu belleğe kaydetmek için kullanılan bir tekniktir. Bu işlevi, öncekiyle aynı argümanlarla yeniden çalıştırmayı denersek, işlevi yeniden yürütmeden, yalnızca ilk işlevin yürütülmesinden önceden kaydedilmiş sonucu döndürür.

Yukarıdaki açıklamayı React ekosistemiyle eşleştirerek, bahsedilen işlevler React bileşenleridir ve argümanlar props'tur.

React.memo() kullanılarak bildirilen bir bileşenin varsayılan davranışı, yalnızca bileşendeki aksesuarlar değiştiğinde işlemesidir. Bunu kontrol etmek için donanımların sığ bir karşılaştırmasını yapar, ancak bunu geçersiz kılmak için bir seçenek mevcuttur.

React.memo() , donanımları değişmeyen veya yeniden oluşturmanın gerekli olmadığı bileşenlerin yeniden oluşturulmasını önleyerek bir React uygulamasının performansını artırır.

Aşağıdaki kod, React.memo() temel sözdizimidir:

 const MemoizedComponent = React.memo((props) => { // Component code goes in here })

React.memo() Ne Zaman Kullanılır?

  • Saf fonksiyonel bileşen
    Bileşeniniz işlevselse, aynı donanıma sahipse ve her zaman aynı çıktıyı React.memo() kullanabilirsiniz. React.memo() 'yu React kancaları ile salt işlevsel olmayan bileşenlerde de kullanabilirsiniz.
  • Bileşen sıklıkla oluşturulur
    Sıklıkla oluşturulan bir bileşeni sarmak için React.memo() 'yu kullanabilirsiniz.
  • Bileşen aynı aksesuarlarla yeniden işleniyor
    Yeniden oluşturma sırasında genellikle aynı aksesuarlarla sağlanan bir bileşeni sarmak için React.memo() kullanın.
  • Orta ila yüksek elementler
    Sahne öğelerinin eşitliğini kontrol etmek için orta ila yüksek sayıda UI öğesi içeren bir bileşen için kullanın.

Not : Geri arama olarak sahne öğelerini kullanan bileşenleri not alırken dikkatli olun. İşlemeler arasında aynı geri çağırma işlevi örneğini kullandığınızdan emin olun. Bunun nedeni, ana bileşenin her işlemede geri çağırma işlevinin farklı örneklerini sağlayabilmesidir, bu da not alma işleminin kesintiye uğramasına neden olur. Bunu düzeltmek için, not alınan bileşenin her zaman aynı geri arama örneğini aldığından emin olun.

Gerçek dünyadaki bir durumda not almayı nasıl kullanabileceğimizi görelim. Aşağıdaki "Photo" adlı işlevsel bileşen, yeniden oluşturmayı önlemek için React.memo() 'yu kullanır.

 export function Photo({ title, views }) { return ( <div> <div>Photo title: {title}</div> <div>Location: {location}</div> </div> ); } // memoize the component export const MemoizedPhoto = React.memo(Photo);

Yukarıdaki kod, fotoğraf başlığını ve fotoğraftaki öznenin konumunu içeren bir div görüntüleyen işlevsel bir bileşenden oluşur. Ayrıca, yeni bir işlev oluşturarak ve onu MemoizedPhoto olarak adlandırarak bileşeni not alıyoruz. Fotoğraf bileşenini not almak, sonraki oluşturmalarda sahne, title ve location aynı olduğu sürece bileşenin yeniden oluşturulmasını önleyecektir.

 // On first render, React calls MemoizedPhoto function. <MemoizedPhoto title="Effiel Tower" location="Paris" /> // On next render, React does not call MemoizedPhoto function, // preventing rendering <MemoizedPhoto title="Effiel Tower" location="Paris" />

Burada React, not alınan işlevi yalnızca bir kez çağırır. Aksesuarlar aynı kaldığı sürece bir sonraki çağrıda bileşeni oluşturmaz.

Paketleme ve Küçültme

React tek sayfalık uygulamalarda, tüm JavaScript kodlarımızı tek bir dosyada toplayabilir ve küçültebiliriz. Uygulamamız nispeten küçük olduğu sürece bu sorun değil.

React uygulamamız büyüdükçe, tüm JavaScript kodlarımızı tek bir dosyada toplamak ve küçültmek sorunlu, anlaşılması zor ve sıkıcı hale geliyor. Tarayıcıya büyük bir JavaScript dosyası gönderdiğimiz için React uygulamamızın performansını ve yükleme süresini de etkileyecektir. Bu nedenle, kod tabanını çeşitli dosyalara bölmemize ve bunları gerektiği gibi aralıklarla tarayıcıya teslim etmemize yardımcı olacak bazı işlemlere ihtiyacımız var.

Böyle bir durumda, Webpack gibi bir tür varlık paketleyici kullanabilir ve ardından uygulamamızı birden çok dosyaya bölmek için kod bölme işlevinden yararlanabiliriz.

Webpack belgelerinde bir uygulamanın yükleme süresini iyileştirmenin bir yolu olarak kod bölme önerilir. Ayrıca, performansı önemli ölçüde artırabilen (yalnızca kullanıcının şu anda ihtiyaç duyduğu şeylere hizmet eden) tembel yükleme için React'in belgelerinde de önerilir.

Webpack, kod bölmeye yönelik üç genel yaklaşım önerir:

  • Giriş noktaları
    Giriş yapılandırmasını kullanarak kodu manuel olarak ayırın.
  • yineleme önleme
    Parçaları çoğaltmak ve bölmek için SplitChunksPlugin kullanın.
  • Dinamik içe aktarma
    Modüller içinde satır içi işlev çağrıları yoluyla kodu ayırın.

Kod Bölmenin Faydaları

  • Kodu bölme, tarayıcının önbellek kaynaklarına ve sık sık değişmeyen koda yardımcı olur.
  • Ayrıca tarayıcının kaynakları paralel olarak indirmesine yardımcı olur, bu da uygulamanın genel yükleme süresini azaltır.
  • Kodu, talep üzerine veya uygulamanın gerektirdiği şekilde yüklenecek parçalara ayırmamızı sağlar.
  • İlk oluşturmada kaynakların ilk indirilmesini nispeten küçük tutar, böylece uygulamanın yükleme süresini azaltır.
Paketleme ve küçültme işlemi
Paketleme ve küçültme işlemi (Büyük önizleme)

Değişmez Veri Yapıları

React'in belgeleri, verileri mutasyona uğratmamanın gücünden bahsediyor. Değiştirilemeyen herhangi bir veri değişmezdir. Değişmezlik, React programcılarının anlaması gereken bir kavramdır.

Değişmez bir değer veya nesne değiştirilemez. Böylece, bir güncelleme olduğunda, eskisine dokunulmadan bellekte yeni bir değer oluşturulur.

Karmaşık bir durum değişikliğini otomatik olarak kontrol etmek için değişmez veri yapılarını ve React.PureComponent kullanabiliriz. Örneğin, uygulamanızdaki durum değişmez ise, Redux gibi bir durum yönetimi kitaplığı ile tüm durum nesnelerini tek bir depoya kaydedebilir, bu da geri alma ve yineleme işlevlerini kolayca uygulamanıza olanak tanır.

Değişmez verileri oluşturulduktan sonra değiştiremeyeceğimizi unutmayın.

Değişmez Veri Yapılarının Faydaları

  • Yan etkileri yoktur.
  • Değişmez veri nesnelerinin oluşturulması, test edilmesi ve kullanılması kolaydır.
  • Verileri tekrar tekrar kontrol etmek zorunda kalmadan, durum güncellemelerini hızlı bir şekilde kontrol etmek için kullanılabilecek mantık yazmamıza yardımcı olurlar.
  • Zamansal eşleşmeyi önlemeye yardımcı olurlar (kodun yürütme sırasına bağlı olduğu bir tür eşleşme).

Aşağıdaki kitaplıklar, bir dizi değişmez veri yapısı sağlamaya yardımcı olur:

  • değişmezlik yardımcısı
    Kaynağı değiştirmeden verilerin bir kopyasını değiştirin.
  • Immutable.js
    JavaScript için değişmez kalıcı veri koleksiyonları, verimliliği ve basitliği artırır.
  • kesintisiz-değişmez
    JavaScript için değişmez veri yapıları, normal JavaScript dizileri ve nesneleri ile geriye dönük uyumlu hale gelir.
  • Tepki-kopyala-yaz
    Bu, değişken bir API ile değişmez bir durum sağlar.

Performansı Artırmanın Diğer Yöntemleri

Dağıtımdan Önce Bir Üretim Yapısı Kullanın

React'in belgeleri, uygulamanızı dağıtırken küçültülmüş üretim yapısını kullanmanızı önerir.

React Developer Tools'un "üretim oluşturma" uyarısı
React Developer Tools'un "üretim oluşturma" uyarısı (Büyük önizleme)

Anonim İşlevlerden Kaçının

Anonim işlevlere bir tanımlayıcı atanmadığından ( const/let/var aracılığıyla), bir bileşen kaçınılmaz olarak yeniden oluşturulduğunda kalıcı değildirler. Bu, JavaScript'in adlandırılmış işlevler kullanılırken olduğu gibi tek bir bellek parçasını yalnızca bir kez tahsis etmek yerine, bu bileşen her yeniden oluşturulduğunda yeni bellek ayırmasına neden olur.

 import React from 'react'; // Don't do this. class Dont extends Component { render() { return ( <button onClick={() => console.log('Do not do this')}> Don't </button> ); } } // The better way class Do extends Component { handleClick = () => { console.log('This is OK'); } render() { return ( <button onClick={this.handleClick}> Do </button> ); } }

Yukarıdaki kod, bir düğmenin tıklandığında bir eylem gerçekleştirmesini sağlamanın iki farklı yolunu gösterir. İlk kod bloğu, onClick() özelliğinde anonim bir işlev kullanır ve bu, performansı etkiler. İkinci kod bloğu, bu senaryoda doğru yol olan onClick() işlevinde adlandırılmış bir işlev kullanır.

Bileşenlerin Montajı ve Sökülmesi Genellikle Pahalıdır

Bir bileşeni yok etmek (yani bağlantısını kesmek) için koşullu ifadeler veya tenaries kullanılması önerilmez, çünkü kaybolması için yapılan bileşen tarayıcının yeniden boyanmasına ve yeniden akmasına neden olur. Belgedeki HTML öğelerinin konumlarının ve geometrilerinin yeniden hesaplanması gerekeceğinden, bu pahalı bir işlemdir. Bunun yerine, bileşeni gizlemek için CSS'nin opacity ve visibility özelliklerini kullanabiliriz. Bu şekilde, bileşen herhangi bir performans maliyeti olmadan DOM'da kalmaya devam eder ancak görünmez olur.

Uzun Listeleri Sanallaştırın

Belgeler, büyük miktarda veri içeren bir liste oluşturuyorsanız, listedeki verilerin küçük bir bölümünü her seferinde görünür görünüm alanı içinde oluşturmanız gerektiğini önerir. Ardından, liste kaydırılırken daha fazla veri oluşturabilirsiniz; bu nedenle, veriler yalnızca görünüm alanındayken görüntülenir. Bu işleme "pencereleme" denir. Pencerelemede, herhangi bir zamanda küçük bir satır alt kümesi oluşturulur. Bunu yapmak için ikisi Brian Vaughn tarafından sağlanan popüler kütüphaneler vardır:

  • tepki penceresi
  • tepki sanallaştırılmış

Çözüm

React uygulamanızın performansını iyileştirmenin başka birkaç yöntemi daha vardır. Bu makale, performans optimizasyonunun en önemli ve etkili yöntemlerini tartıştı.

Umarım bu öğreticiyi okumaktan zevk almışsınızdır. Aşağıda listelenen kaynaklar aracılığıyla daha fazla bilgi edinebilirsiniz. Herhangi bir sorunuz varsa, bunları aşağıdaki yorumlar bölümünde bırakın. Her birine memnuniyetle cevap vereceğim.

Referanslar ve İlgili Kaynaklar

  • "Performansı Optimize Etme", React Docs
  • “React.memo'yu Akıllıca Kullanın”, Dmitri Pavlutin
  • “React'te Performans Optimizasyon Teknikleri”, Niteesh Yadav
  • "React'te Değişmezlik: Mutasyona Uğrayan Nesnelerde Yanlış Bir Şey Yok", Esteban Herrera
  • “React Uygulamanızın Performansını Optimize Etmenin 10 Yolu”, Chidume Nnamdi
  • “React Uygulamalarınızın Performansını Artırmak için 5 İpucu”, William Le