React işleme performansındaki darboğazları en kolay şekilde nasıl belirleyebilirim?

Aug 15 2020

JSON görüntüleyici üzerinde çalışırken işleme performansındaki darboğazları tespit etmede sorun yaşıyorum. Birkaç öğe ile iyi performans gösterir, ancak belirli bir noktada can sıkıcı bir şekilde yavaşlar.

Profil oluşturucuyu kontrol ederken, öğeler yeterince hızlı işliyor gibi görünüyor, ancak nasıl devam edeceğimi bilmediğim birkaç sorun fark ettim.

Genel Bakış

  • Uygulama, tek tek öğelerin yanı sıra tüm öğeleri aynı anda genişletmenize / küçültmenize olanak tanıyan bir JSON görüntüleyicidir.
  • Performans, birkaç öğeyle iyidir, ancak öğelerin sayısı arttıkça çarpıcı bir şekilde düşüyor gibi görünüyor.
  • performance.now()React DevTools'ta hem nesne filtre yöntemimin profilini çıkarırken hem de işleme süresini kontrol ederken, rakamlar iyi görünüyor. Yanlış yorumluyor olabilirim.
  • React.memo()Durum bilgisi olmayan öğeler (özellikle en sık işlenen bileşen olan anahtar / değer) kullanmayı denedim , ancak performansı gözle görülür şekilde iyileştirmiyor gibi görünüyor. Kuşkusuz, bunu yararlı bir şekilde uygulamak için React bileşenlerini hatırlamanın arkasındaki mantığı yeterince anladığımdan emin değilim.

Uygulama

  • Şu anda uygulamam, verileri bir özyinelemeli öğe kullanarak JSON ağacını yükleyen bir bileşene beslenen bir üst öğeye yüklüyor.
  • URL'den JSON beslemesinin yüklenmesi, bir giriş alanına girilen değerleri kullanan bir yardımcı yöntem kullanılarak filtrelenen üst bileşenin durumunu değiştirir.

Sorunlar

JSON belgeleriyle (çok büyük olmayan) yavaş yanıt süresi oluşturan iki işlev vardır:

  • Tümünü genişlet düğmesi
  • Bir filtre sorgusundaki ilk birkaç tuşa basma

Mevcut uygulamayla birlikte, tüm filtreleme ve genişletme display: none, alt öğelerde bir değişikliği tetikliyor ve davranış, bu kullanım örneğini ele almak için verimsiz bir şey yaptığıma inanmamı sağlıyor.

Üreme Adımları

Kod burada mevcuttur: https://codesandbox.io/s/react-json-view-4z348

Burada bir üretim derlemesiyle (daha iyi performans göstermiyor): https://csb-4z348.vercel.app/

Sorunu yeniden oluşturmak için Tümünü Genişlet işlevi (filtre girişinin yanındaki artı işareti) ve bazı filtre girişleriyle oynayın.

Ardından, daha fazla öğe içeren bir JSON feed'i yüklemeyi deneyin ( GitHub API feed'imde test edebilirsiniz ) ve tümünü filtrelemeyi / genişletmeyi deneyin. Önemli performans artışına dikkat edin.

Ne fark ettim

  • UseEffect'i günlüğe kaydederken, simge durumuna küçültme, hepsini genişletmek kadar ~ 2 kat daha fazla yeniden oluşturucuya neden oluyor gibi görünüyor.
  • Filtre girdisi daha spesifik hale geldikçe, daha az öğe işlendikçe performans (mantıksal olarak) artar.

Soru

Bu özel durum için doğru yöndeki bir dürtüyü takdir etsem de, en çok merak ettiğim şey, bu performans sorunlarına neyin neden olduğunu en iyi nasıl belirleyeceğim.

Çıktıyı pencereye inceledim, ancak bu benim ilk tercihim değil ve çok fazla öğenin işlenmesinin nedeni yerine yanlış bir şeyler yaptığımdan oldukça eminim.

Zaman ayırdığınız için minnettarım ve verebileceğiniz tüm ipuçları için şimdiden teşekkür ederim!

Yanıtlar

2 HarrisonGrieve Aug 16 2020 at 15:50

Görünüşe göre kendi sorumu cevapladım. Sorun, UUID'yi alt bileşenlerimde anahtar destek olarak kullanmaktan kaynaklanan bir mutabakat sorunuydu ve bu durum, simge durumuna küçültme durumu her değiştiğinde yeniden oluşturmalarına neden oluyordu. Dokümanlardan:

Anahtarlar kararlı, tahmin edilebilir ve benzersiz olmalıdır. Kararsız anahtarlar (Math.random () tarafından üretilenler gibi) birçok bileşen örneğinin ve DOM düğümlerinin gereksiz şekilde yeniden oluşturulmasına neden olur ve bu da alt bileşenlerde performans düşüşüne ve durum kaybına neden olabilir.

Bu sorunla karşılaşan diğer herkes için buradaki adımları bırakacağım.


Performans profilleyicisinde (çok uzun süre) kazı yaptıktan sonra, öğeleri her küçülttüğümde veya genişlettiğimde, her çocuğun tekrar monte edildiğini fark ettim. Google'a daha spesifik bir sorgu ile danıştıktan sonra, bu blog gönderisini buldum ve bu bariz performans hatasını yaptığımı fark ettim.

Sorunun kaynağını bulduğumda, başka birçok referans buldum .

Anahtar pervaneyi düzelttikten sonra, tümünü küçültmek / genişletmek için etkileşim süresi ~% 60 daha hızlı oldu.

Son olarak, anlık filtre ile ilgili diğer bazı bileşenleri de ezberledim ve sonunda şu an istediğim kadar iyi performans gösteriyor gibi görünüyor.

Bu arada buna göz atan herkese teşekkürler ve umarım bununla karşılaşabilecek herkes için yararlıdır.