AirSHIFT'ın React uygulamasının çalışma zamanı performansını iyileştirmesinin beş yolu

React SPA performans optimizasyonuyla ilgili gerçek bir örnek olay.

Kento Tsuji
Kento Tsuji
Satoshi Arai
Satoshi Arai
Yusuke Utsunomiya
Yusuke Utsunomiya
Yosuke Furukawa
Yosuke Furukawa

Web sitesi performansı yalnızca yükleme süresiyle ilgili değildir. Özellikle kullanıcıların her gün kullandığı üretkenlik masaüstü uygulamaları için kullanıcılara hızlı ve duyarlı bir deneyim sunmak çok önemlidir. Recruit Technologies'ın mühendislik ekibi, web uygulamalarından biri olan AirSHIFT'i kullanıcı girişi performansını iyileştirmek için yeniden yapılandırmaya tabi tuttu. Nasıl başarılı olduklarını anlatacağım.

Yavaş yanıt, daha düşük üretkenlik

AirSHIFT, restoran ve kafe gibi mağaza sahiplerinin personellerinin vardiyalı çalışma düzenini yönetmesine yardımcı olan bir masaüstü web uygulamasıdır. React ile oluşturulan tek sayfalık uygulama, gün, hafta, ay vb. bazı ölçütlere göre düzenlenmiş vardiya programlarının çeşitli tabloları da dahil olmak üzere zengin müşteri özellikleri sunar.

AirSHIFT web uygulamasının ekran görüntüsü.

Recruit Technologies mühendislik ekibi, AirSHIFT uygulamasına yeni özellikler ekledikçe yavaş performansla ilgili daha fazla geri bildirim almaya başladı. AirSHIFT'in mühendislik yöneticisi Yosuke Furukawa şunları söyledi:

Bir kullanıcı araştırması çalışmasında, mağaza sahiplerinden biri, vardiya tablosunun yüklenmesini beklerken zaman geçirmek için düğmeyi tıkladıktan sonra koltuğundan kalkıp kahve yaptığını söyledi. Bu durum bizi şaşırttı.

Araştırmayı inceleyen mühendislik ekibi, kullanıcılarının çoğunun 10 yıllık 1 GHz Celeron M dizüstü bilgisayar gibi düşük özellikli bilgisayarlara büyük vardiya tabloları yüklemeye çalıştığını fark etti.

Düşük kaliteli cihazlarda sonsuz döndürme düğmesi.

AirSHIFT uygulaması, ana mesaj dizisini pahalı komut dosyalarıyla engelliyordu ancak mühendislik ekibi, hızlı kablosuz bağlantılara sahip zengin özellikli bilgisayarlarda geliştirme ve test yaptığı için komut dosyalarının ne kadar pahalı olduğunu fark etmemişti.

Uygulamanın çalışma zamanı etkinliğini gösteren bir grafik.
Vardiya tablosu yüklenirken yükleme süresinin yaklaşık% 80'i komut dosyalarının çalıştırılmasıyla tüketiliyordu.

Chrome Geliştirici Araçları'nda CPU ve ağ tarama özelliği etkinken performanslarının profilini oluşturduktan sonra, performans optimizasyonuna ihtiyaç duyulduğu anlaşıldı. AirSHIFT bu sorunu çözmek için bir görev gücü oluşturdu. Uygulamalarını kullanıcı girişlerine daha duyarlı hale getirmek için odaklandıkları 5 konuyu aşağıda bulabilirsiniz.

1. Büyük tabloları sanallaştırma

Vardiya tablosunu görüntülemek için birden fazla pahalı adım gerekiyordu: Sanal DOM'u oluşturma ve personel sayısına ve zaman aralıklarını orantılı olarak ekranda oluşturma. Örneğin, bir restoranda 50 çalışan varsa ve aylık vardiya programlarını kontrol etmek istiyorsa 50 (çalışan) ile 30 (gün) çarpımı olan bir tablo oluşturulur. Bu tabloda oluşturulacak 1.500 hücre bileşeni olur. Bu işlem, özellikle düşük özellikli cihazlar için çok pahalıdır. Gerçekte durum daha kötüydü. Araştırma sonucunda, 200 personel yöneten mağazalar olduğunu ve tek bir aylık tabloda yaklaşık 6.000 hücre bileşeni gerektiğini öğrendiler.

AirSHIFT, bu işlemin maliyetini azaltmak için vardiya tablosunu sanallaştırdı. Uygulama artık yalnızca görüntü alanındaki bileşenleri monte eder ve ekran dışındaki bileşenlerin montajını kaldırır.

AirSHIFT'in, içeriği görüntü alanının dışında oluşturmak için kullanıldığını gösteren ek açıklamalı ekran görüntüsü.
Önce: Tüm vardiya tablosu hücreleri oluşturulur.
AirSHIFT'in artık yalnızca görüntü alanında görünen içeriği oluşturduğunu gösteren, not eklenmiş bir ekran görüntüsü.
Sonra: Yalnızca görüntü alanındaki hücreler oluşturulur.

Bu durumda AirSHIFT, karmaşık iki boyutlu ızgara tablolarını etkinleştirmeyle ilgili şartlar olduğu için react-virtualized'ı kullandı. Ayrıca, uygulamayı gelecekte hafif react-window kullanmak üzere dönüştürmenin yollarını araştırıyorlar.

Sonuçlar

Yalnızca tabloyu sanallaştırmak, komut dosyası yazma süresini 6 saniye azalttı (4x CPU yavaşlatma + Hızlı 3G'de kısıtlanmış Macbook Pro ortamında). Bu, yeniden düzenleme projesinde en etkili performans iyileştirmesiydi.

Chrome Geliştirici Araçları Performans paneli kaydının notlarla açıklanmış ekran görüntüsü.
Önce: Kullanıcı girişinden sonra yaklaşık 10 saniyelik komut dosyası.
Chrome Geliştirici Araçları Performans paneli kaydının notlarla açıklanmış başka bir ekran görüntüsü.
Sonra: Kullanıcı girişinden 4 saniye sonra komut dosyası çalıştırma.

2. User Timing API ile denetleme

Ardından AirSHIFT ekibi, kullanıcı girişinde çalışan komut dosyalarını yeniden yapılandırdı. Chrome Geliştirici Araçları'nın alev grafiği, ana iş parçacığında gerçekte neler olduğunu analiz etmenizi sağlar. Ancak AirSHIFT ekibi, React'in yaşam döngüsüne dayalı olarak uygulama etkinliğini analiz etmeyi daha kolay buldu.

React 16, performans izlemesini User Timing API aracılığıyla sağlar. Bu performans izlemeyi Chrome Geliştirici Araçları'nın Zamanlamalar bölümünden görselleştirebilirsiniz. AirSHIFT, React yaşam döngüsü etkinliklerinde çalışan gereksiz mantığı bulmak için Zamanlamalar bölümünü kullandı.

Chrome Geliştirici Araçları'nın Performans panelindeki Zamanlamalar bölümü.
React'in kullanıcı zamanlaması etkinlikleri.

Sonuçlar

AirSHIFT ekibi, her rota gezinmesinden hemen önce gereksiz bir React Tree Reconciliation işleminin gerçekleştiğini keşfetti. Bu, React'in gezinmelerden önce vardiya tablosunu gereksiz yere güncellediği anlamına geliyordu. Bu soruna, gereksiz bir Redux durum güncellemesi neden oluyordu. Bu sorunu düzeltmek, komut dosyası yazma süresinde yaklaşık 750 ms tasarruf sağladı. AirSHIFT, komut dosyası yazma süresinde toplam 1 saniyelik bir azalmaya yol açan diğer mikro optimizasyonları da yaptı.

3. Bileşenleri yavaşça yükleyin ve pahalı mantığı web işçilerine taşıyın

AirSHIFT'te yerleşik bir sohbet uygulaması vardır. Birçok mağaza sahibi, vardiya tablosuna bakarken personeliyle sohbet üzerinden iletişim kurar. Bu nedenle, tablo yüklenirken kullanıcı mesaj yazabilir. Ana ileti dizisi, tabloyu oluşturan komut dosyalarıyla meşgulse kullanıcı girişi sorunlu olabilir.

AirSHIFT, bu deneyimi iyileştirmek için artık gerçek bileşenleri yavaşça yüklerken tablo içerikleri için yer tutucular göstermek üzere React.lazy ve Suspense'i kullanıyor.

AirSHIFT ekibi, yavaş yüklenmiş bileşenlerdeki pahalı iş mantığının bir kısmını web işçilerine de taşıdı. Bu işlem, ana iş parçacığının kullanıcı girişine yanıt vermeye odaklanabilmesi için ana iş parçacığının boşaltılmasıyla kullanıcı girişi takılma sorununu çözdü.

Geliştiriciler genellikle işçileri kullanma konusunda karmaşıklıkla karşılaşır ancak bu kez Comlink onlar için ağır işleri üstlendi. Aşağıda, AirSHIFT'in en pahalı operasyonlarından birini (toplam işçilik maliyetlerini hesaplama) nasıl işçileştirdiğine dair sözde kod verilmiştir.

Yükleme sırasında yedek içeriği göstermek için App.js'de React.lazy ve Suspense'i kullanın

/** App.js */
import React, { lazy, Suspense } from 'react'

// Lazily loading the Cost component with React.lazy
const Hello = lazy(() => import('./Cost'))

const Loading = () => (
 
<div>Some fallback content to show while loading</div>
)

/
/ Showing the fallback content while loading the Cost component by Suspense
export default function App({ userInfo }) {
   
return (
   
<div>
     
<Suspense fallback={<Loading />}>
       
<Cost />
     
</Suspense>
    </
div>
 
)
}

Maliyet bileşeninde, hesaplama mantığını yürütmek için comlink'i kullanın

/** Cost.js */
import React from 'react';
import { proxy } from 'comlink';

// import the workerlized calc function with comlink
const WorkerlizedCostCalc = proxy(new Worker('./WorkerlizedCostCalc.js'));
export default async function Cost({ userInfo }) {
 
// execute the calculation in the worker
 
const instance = await new WorkerlizedCostCalc();
 
const cost = await instance.calc(userInfo);
 
return <p>{cost}</p>;
}

İşleyicide çalışan hesaplama mantığını uygulayın ve comlink ile gösterin

// WorkerlizedCostCalc.js
import { expose } from 'comlink'
import { someExpensiveCalculation } from './CostCalc.js'

// Expose the new workerlized calc function with comlink
expose
({
  calc
(userInfo) {
   
// run existing (expensive) function in the worker
   
return someExpensiveCalculation(userInfo);
 
}
}, self);

Sonuçlar

Deneme olarak sınırlı miktarda mantığı çalışana dönüştüren AirSHIFT, JavaScript'lerinin yaklaşık 100 ms'sini ana iş parçacığından çalışan iş parçacığına taşıdı (4x CPU throttling ile simüle edildi).

Komut dosyasının artık ana iş parçacığı yerine bir web işçisinde gerçekleştiğini gösteren Chrome Geliştirici Araçları Performans paneli kaydının ekran görüntüsü.

AirSHIFT şu anda diğer bileşenleri gecikmeli olarak yükleyip yükleyemeyeceklerini ve gecikmeyi daha da azaltmak için web işçilerine daha fazla mantık aktarıp aktaramayacaklarını araştırıyor.

4. Performans bütçesi belirleme

Tüm bu optimizasyonları uyguladıktan sonra, uygulamanın zaman içinde performansının korunmasını sağlamak kritik öneme sahipti. AirSHIFT artık mevcut JavaScript ve CSS dosya boyutunu aşmamak için bundlesize değerini kullanıyor. Bu temel bütçeleri belirlemenin yanı sıra, uygulamanın ideal olmayan koşullarda bile performanslı olup olmadığını kontrol etmek için vardiya tablosu yükleme süresinin çeşitli yüzdelik dilimlerini gösteren bir kontrol paneli oluşturdular.

  • Artık her Redux etkinliğinin komut dosyası tamamlama süresi ölçülecek
  • Performans verileri Elasticsearch'te toplanır.
  • Her etkinliğin 10., 25., 50. ve 75. yüzdelik dilim performansı Kibana ile görselleştirilir.

AirSHIFT artık vardiya tablosu yükleme etkinliğini izleyerek 75. yüzdelik dilimdeki kullanıcılar için 3 saniyede tamamlanmasını sağlıyor. Bu bütçe şu anda zorunlu tutulmuyor ancak bütçelerini aştıklarında Elasticsearch üzerinden otomatik bildirimler göndermeyi düşünüyorlar.

75. yüzdelik dilimin yaklaşık 2.500 ms, 50. yüzdelik dilimin yaklaşık 1.250 ms, 25. yüzdelik dilimin yaklaşık 750 ms ve 10. yüzdelik dilimin yaklaşık 500 ms içinde tamamlandığını gösteren bir grafik.
Yüzdelik dilimlere göre günlük performans verilerini gösteren Kibana kontrol paneli.

Sonuçlar

Yukarıdaki grafikte, AirSHIFT'in artık çoğunlukla 75. yüzdelik dilimdeki kullanıcılar için 3 saniyelik bütçeye ulaştığını ve ayrıca 25. yüzdelik dilimdeki kullanıcılar için vardiya tablosunu bir saniye içinde yüklediğini görebilirsiniz. AirSHIFT, çeşitli koşullardan ve cihazlardan RUM performans verilerini yakalayarak yeni bir özellik sürümünün uygulamanın performansını gerçekten etkileyip etkilemediğini kontrol edebilir.

5. Performans hackathon'ları

Tüm bu performans optimizasyonu çalışmaları önemli ve etkili olsa da mühendislik ve işletme ekiplerinin işlevsel olmayan geliştirmeye öncelik vermesini sağlamak her zaman kolay değildir. Bu performans optimizasyonlarından bazıları planlanamadığı için bu durum bir sorun teşkil ediyor. Deneme ve yanılma yöntemini uygulamayı gerektirir.

AirSHIFT, mühendislerin yalnızca performansla ilgili çalışmalara odaklanabilmesi için artık şirket içinde 1 günlük performans hackathonları düzenliyor. Bu hackathon'larda tüm kısıtlamalar kaldırılır ve mühendislerin yaratıcılığına saygı gösterilir. Diğer bir deyişle, hıza katkıda bulunan tüm uygulamalar dikkate alınır. AirSHIFT, hackathon'u hızlandırmak için grubu küçük ekiplere ayırır ve her ekip, en büyük Lighthouse performans puanı artışını elde etmek için yarışır. Ekipler çok rekabetçi oluyor. 🔥

Hackathon&#39;un fotoğrafları.

Sonuçlar

Hackathon yaklaşımı onlar için iyi sonuç veriyor.

  • Hackathon sırasında birden fazla yaklaşımı deneyip her birini Lighthouse ile ölçerek performans darboğazlarını kolayca tespit edebilirsiniz.
  • Hackathon'dan sonra, ekibi üretim sürümüne öncelik vermeleri gereken optimizasyona ikna etmek oldukça kolaydır.
  • Ayrıca hızın önemini vurgulamanın etkili bir yoludur. Her katılımcı, kodlama şekliniz ile performans arasındaki ilişkiyi anlayabilir.

Bu yaklaşımın olumlu bir yan etkisi de Recruit'taki diğer birçok mühendislik ekibinin bu uygulamalı yaklaşıma ilgi duyması oldu. AirSHIFT ekibi şu anda şirket içinde birden fazla hız hackathon'u düzenliyor.

Özet

AirSHIFT'in bu optimizasyonlar üzerinde çalışması kesinlikle en kolay yolculuk değildi ancak kesinlikle karşılığını aldı. AirSHIFT artık vardiya tablosunu ortalama 1,5 saniye içinde yüklüyor.Bu, proje öncesi performanslarına kıyasla 6 katlık bir iyileşme.

Performans optimizasyonları kullanıma sunulduktan sonra bir kullanıcı şunları söyledi:

Vardiya tablosunun hızlı yüklenmesini sağladığınız için çok teşekkür ederiz. Vardiyalı çalışmayı düzenlemek artık çok daha verimli.