React SPA की परफ़ॉर्मेंस को ऑप्टिमाइज़ करने से जुड़ी केस स्टडी.
वेबसाइट की परफ़ॉर्मेंस सिर्फ़ लोड होने में लगने वाले समय पर निर्भर नहीं करती. उपयोगकर्ताओं को तेज़ और रिस्पॉन्सिव अनुभव देना ज़रूरी है. खास तौर पर, उन डेस्कटॉप ऐप्लिकेशन के लिए जो लोगों के काम के हैं और जिन्हें वे रोज़ इस्तेमाल करते हैं. Recruit Technologies की इंजीनियरिंग टीम ने अपने एक वेब ऐप्लिकेशन, AirSHIFT को बेहतर बनाने के लिए, रीफ़ैक्टर करने का प्रोजेक्ट शुरू किया. इससे, उपयोगकर्ता इनपुट की परफ़ॉर्मेंस बेहतर हुई. उन्होंने ऐसा कैसे किया, यह जानने के लिए यहां देखें.
इसकी रफ़्तार धीमी है, लेकिन प्रॉडक्टिविटी कम होती है
AirSHIFT एक डेस्कटॉप वेब ऐप्लिकेशन है. यह रेस्टोरेंट और कैफ़े जैसे स्टोर मालिकों को अपने स्टाफ़ के सदस्यों के शिफ़्ट होने के काम को मैनेज करने में मदद करता है. React के साथ बनाया गया यह सिंगल पेज ऐप्लिकेशन, रिच क्लाइंट की सुविधाएं देता है. इनमें, दिन, हफ़्ते, महीने वगैरह के हिसाब से व्यवस्थित किए गए शिफ़्ट शेड्यूल की अलग-अलग ग्रिड टेबल शामिल हैं.
जैसे ही Recruit Technologies इंजीनियरिंग टीम ने AirSHIFT ऐप्लिकेशन में नई सुविधाएं जोड़ी हैं, उसे धीमे परफ़ॉर्मेंस के बारे में ज़्यादा सुझाव मिलने लगे हैं. AirSHIFT के इंजीनियरिंग मैनेजर, योसुके फ़ुरूकावा ने कहा:
उपयोगकर्ता के बारे में की गई रिसर्च में, हमें यह जानकर हैरानी हुई कि स्टोर के एक मालिक ने बताया कि वह बटन पर क्लिक करने के बाद, कॉफ़ी बनाने के लिए अपनी सीट छोड़ देती है. ऐसा सिर्फ़ इसलिए करती है, ताकि शिफ़्ट टेबल लोड होने तक वह समय बर्बाद न करे.
रिसर्च के बाद, इंजीनियरिंग टीम को पता चला कि उनके कई उपयोगकर्ता, कम सुविधाओं वाले कंप्यूटर पर बहुत बड़ी शिफ़्ट टेबल लोड करने की कोशिश कर रहे थे. जैसे, 10 साल पहले का 1 GHz Celeron M लैपटॉप.
AirSHIFT ऐप्लिकेशन महंगे स्क्रिप्ट वाले मुख्य थ्रेड को ब्लॉक कर रहा था, लेकिन इंजीनियरिंग टीम को यह पता नहीं चला कि स्क्रिप्ट कितनी महंगी थीं, क्योंकि वे तेज़ वाई-फ़ाई कनेक्शन वाले रिच खास कंप्यूटर पर डेवलप और टेस्ट कर रही थीं.
सीपीयू और नेटवर्क थ्रॉटलिंग की सुविधा चालू होने पर, Chrome DevTools में उनकी परफ़ॉर्मेंस की प्रोफ़ाइल बनाने के बाद, यह बात साफ़ हो गई कि परफ़ॉर्मेंस ऑप्टिमाइज़ेशन की ज़रूरत है. AirSHIFT ने इस समस्या से निपटने के लिए एक टास्क फ़ोर्स का गठन किया. उपयोगकर्ता के इनपुट के हिसाब से अपने ऐप्लिकेशन को ज़्यादा बेहतर बनाने के लिए, उन्होंने इन पांच बातों पर फ़ोकस किया.
1. बड़ी टेबल को वर्चुअलाइज़ करना
शिफ़्ट टेबल दिखाने के लिए, कई महंगे चरण पूरे करने पड़ते हैं: वर्चुअल डीओएम बनाना और स्टाफ़ सदस्यों की संख्या और टाइम स्लॉट के हिसाब से, इसे स्क्रीन पर रेंडर करना. उदाहरण के लिए, अगर किसी रेस्टोरेंट में 50 कामकाजी सदस्य हैं और आपको हर महीने की शिफ़्ट के शेड्यूल को देखना है, तो 50 (सदस्यों) को 30 (दिनों) से गुणा करने वाली टेबल होगी. इससे सेल के 1,500 कॉम्पोनेंट रेंडर हो जाएंगे. यह प्रोसेस बहुत महंगी होती है. खास तौर पर, कम स्पेसिफ़िकेशन वाले डिवाइसों के लिए. असल में, स्थिति और भी खराब थी. रिसर्च से उन्हें पता चला कि 200 कर्मचारियों को मैनेज करने वाली दुकानों के लिए, हर महीने की एक टेबल में करीब 6,000 सेल कॉम्पोनेंट की ज़रूरत होती है.
इस प्रोसेस की लागत कम करने के लिए, AirSHIFT ने शिफ़्ट टेबल को वर्चुअल कर दिया. अब ऐप्लिकेशन सिर्फ़ व्यूपोर्ट में कॉम्पोनेंट माउंट करता है और ऑफ़-स्क्रीन कॉम्पोनेंट को अनमाउंट करता है.
इस मामले में, AirSHIFT ने रिऐक्ट-वर्चुअलाइज़्ड का इस्तेमाल किया, क्योंकि दो डाइमेंशन वाली ग्रिड टेबल को चालू करने के लिए ज़रूरी शर्तें थीं. वे आने वाले समय में, कम साइज़ वाले react-window का इस्तेमाल करने के लिए, इसे लागू करने के तरीकों को बदलने के बारे में भी सोच रहे हैं.
नतीजे
सिर्फ़ टेबल को वर्चुअलाइज़ करने से, स्क्रिप्टिंग में लगने वाला समय छह सेकंड कम हो गया. ऐसा, सीपीयू के चार गुना धीमे होने और फ़ास्ट 3G की स्पीड कम होने के बावजूद हुआ. रीफ़ैक्टर करने के प्रोजेक्ट में, परफ़ॉर्मेंस में यह सबसे ज़्यादा असरदार सुधार था.
2. User Timing API की मदद से ऑडिट करें
इसके बाद, AirSHIFT की टीम ने उपयोगकर्ता के इनपुट पर चलने वाली स्क्रिप्ट को फिर से तैयार किया. Chrome DevTools के फ़्लेम चार्ट की मदद से, यह पता लगाया जा सकता है कि मुख्य थ्रेड में क्या हो रहा है. हालांकि, AirSHIFT की टीम को React की लाइफ़साइकल के आधार पर, ऐप्लिकेशन की गतिविधि का विश्लेषण करना ज़्यादा आसान लगा.
React 16, User Timing API के ज़रिए अपनी परफ़ॉर्मेंस का ट्रेस उपलब्ध कराता है. इसे Chrome DevTools के समय सेक्शन से देखा जा सकता है. AirSHIFT ने React लाइफ़साइकल इवेंट में चल रहे ग़ैर-ज़रूरी लॉजिक का पता लगाने के लिए, टाइमिंग सेक्शन का इस्तेमाल किया.
नतीजे
AirSHIFT की टीम को पता चला कि हर रूट के नेविगेशन से ठीक पहले रिऐक्ट ट्री समाधान की एक ग़ैर-ज़रूरी घटना हो रही थी. इसका मतलब था कि React, नेविगेशन से पहले शिफ़्ट टेबल को बिना ज़रूरत के अपडेट कर रहा था. Redux से जुड़े गैर-ज़रूरी अपडेट की वजह से यह समस्या हो रही थी. इसे ठीक करने से, स्क्रिप्टिंग में करीब 750 मिलीसेकंड की बचत हुई. AirSHIFT ने कुछ और माइक्रो ऑप्टिमाइज़ेशन भी किए, जिसकी वजह से स्क्रिप्टिंग में लगने वाला कुल समय एक सेकंड कम हो गया.
3. कॉम्पोनेंट को लेज़ी लोड करना और ज़्यादा खर्च वाले लॉजिक को वेब वर्कर्स पर ले जाना
AirSHIFT में चैट करने की सुविधा पहले से मौजूद है. कई स्टोर मालिक, शिफ़्ट टेबल देखते समय चैट की मदद से अपने स्टाफ़ से बातचीत करते हैं. इसका मतलब है कि टेबल लोड होने के दौरान, कोई उपयोगकर्ता मैसेज टाइप कर सकता है. अगर मुख्य थ्रेड, टेबल को रेंडर करने वाली स्क्रिप्ट में व्यस्त है, तो उपयोगकर्ता का इनपुट अनियमित हो सकता है.
इस अनुभव को बेहतर बनाने के लिए, AirSHIFT अब React.lazy और Suspense का इस्तेमाल करता है. इससे, टेबल के कॉन्टेंट के लिए प्लेसहोल्डर दिखाए जाते हैं, जबकि असल कॉम्पोनेंट को धीरे-धीरे लोड किया जाता है.
AirSHIFT की टीम ने लेज़ी तरीके से लोड होने वाले कॉम्पोनेंट के अंदर के कुछ महंगे बिज़नेस लॉजिक को भी वेब वर्कर पर माइग्रेट कर दिया है. इससे मुख्य थ्रेड को खाली करके, उपयोगकर्ता इनपुट की समस्या को हल किया गया, ताकि वह उपयोगकर्ता इनपुट का जवाब देने पर फ़ोकस कर सके.
आम तौर पर, डेवलपर को वर्कर्स का इस्तेमाल करने में मुश्किल होती है. हालांकि, इस बार Comlink ने उनके लिए ज़्यादातर काम किया. यहां एक स्यूडो कोड दिया गया है, जिससे पता चलता है कि AirSHIFT ने किस तरह अब तक के सबसे महंगे ऑपरेशन में से एक को पूरा किया: कामगारों की कुल लागत का हिसाब लगाना.
ऐप्लिकेशन लोड होने के दौरान फ़ॉलबैक कॉन्टेंट दिखाने के लिए, App.js में React.lazy और Suspense का इस्तेमाल करना चाहिए
/** 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>
)
}
लागत कॉम्पोनेंट में, कैलकुलेशन लॉजिक को लागू करने के लिए comlink का इस्तेमाल करना
/** 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>;
}
वर्कर्स में चलने वाले कैलकुलेशन लॉजिक को लागू करना और उसे comlink की मदद से एक्सपोज़ करना
// 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);
नतीजे
ट्रायल के तौर पर काम करने वाले तर्क के सीमित होने के बावजूद, AirSHIFT ने अपने JavaScript के करीब 100 मि॰से॰ को मुख्य थ्रेड से वर्कर थ्रेड में शिफ़्ट कर दिया है (4x सीपीयू थ्रॉटलिंग के साथ सिम्युलेट किया गया).
फ़िलहाल, AirSHIFT यह पता लगा रहा है कि क्या वे अन्य कॉम्पोनेंट को लैज़ी लोड कर सकते हैं और वेब वर्कर पर ज़्यादा लॉजिक ऑफ़लोड करके, जंक को और कम किया जा सकता है.
4. परफ़ॉर्मेंस बजट सेट करना
इन सभी ऑप्टिमाइज़ेशन को लागू करने के बाद, यह पक्का करना ज़रूरी था कि ऐप्लिकेशन समय के साथ बेहतर परफ़ॉर्म करता रहे. AirSHIFT अब bundlesize का इस्तेमाल करता है, ताकि मौजूदा JavaScript और सीएसएस फ़ाइल का साइज़ ज़्यादा न हो. इन बुनियादी बजट को सेट करने के अलावा, उन्होंने एक डैशबोर्ड बनाया है. इससे, शिफ़्ट टेबल लोड होने में लगने वाले समय के अलग-अलग प्रतिशत को दिखाया जा सकता है. इससे यह पता चलता है कि ऐप्लिकेशन, सही परिस्थितियों में भी अच्छा परफ़ॉर्म कर रहा है या नहीं.
- हर Redux इवेंट के लिए, स्क्रिप्ट पूरा होने का समय अब मेज़र किया जाता है
- परफ़ॉर्मेंस डेटा को Elasticsearch में इकट्ठा किया जाता है
- हर इवेंट की 10वें, 25वें, 50वें, और 75वें पर्सेंटाइल की परफ़ॉर्मेंस को किबाना की मदद से विज़ुअलाइज़ किया गया है
AirSHIFT अब शिफ़्ट टेबल लोड होने के इवेंट को मॉनिटर कर रहा है, ताकि यह पक्का किया जा सके कि यह 75वें प्रतिशत के उपयोगकर्ताओं के लिए तीन सेकंड में पूरा हो जाए. फ़िलहाल, यह एक ऐसा बजट है जिसे लागू नहीं किया गया है. हालांकि, अपने बजट से ज़्यादा खर्च होने पर, कंपनी Elasticsearch से अपने-आप सूचनाएं पाने की सुविधा पर विचार कर रही है.
नतीजे
ऊपर दिए गए ग्राफ़ से पता चलता है कि AirSHIFT अब 75वें पर्सेंटाइल के उपयोगकर्ताओं के लिए, ज़्यादातर तीन सेकंड के बजट को पूरा कर रहा है. साथ ही, 25वें पर्सेंटाइल के उपयोगकर्ताओं के लिए, एक सेकंड में शिफ़्ट टेबल लोड कर रहा है. अलग-अलग स्थितियों और डिवाइसों से RUM की परफ़ॉर्मेंस का डेटा कैप्चर करके, AirSHIFT अब यह जांच कर सकता है कि किसी नई सुविधा के रिलीज़ होने से, ऐप्लिकेशन की परफ़ॉर्मेंस पर असल में असर पड़ रहा है या नहीं.
5. परफ़ॉर्मेंस हैकेथॉन
परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए किए गए ये सभी काम ज़रूरी और असरदार थे. हालांकि, इंजीनियरिंग और कारोबार की टीमों को, काम न करने वाले डेवलपमेंट को प्राथमिकता देना हमेशा आसान नहीं होता. समस्या का एक हिस्सा यह है कि परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के कुछ तरीकों को प्लान नहीं किया जा सकता. इनके लिए, एक्सपेरिमेंट करने के साथ-साथ कुछ नया आज़माने की ज़रूरत होती है.
AirSHIFT अब एक दिन के इंटरनल परफ़ॉर्मेंस हैकथॉन आयोजित कर रहा है, ताकि इंजीनियर सिर्फ़ परफ़ॉर्मेंस से जुड़े काम पर फ़ोकस कर सकें. इन हैकथॉन में, वे सभी पाबंदियों को हटा देते हैं और इंजीनियरों की क्रिएटिविटी का सम्मान करते हैं. इसका मतलब है कि तेज़ी से काम करने में मदद करने वाले किसी भी सुझाव पर विचार किया जा सकता है. हैकेथॉन (सॉफ़्टवेयर डेवलपमेंट इवेंट) में तेज़ी लाने के लिए, AirSHIFT ने ग्रुप को छोटी-छोटी टीमों में बांट दिया है. साथ ही, हर टीम यह देखने के लिए मुकाबला करती है कि Lighthouse परफ़ॉर्मेंस स्कोर में सबसे ज़्यादा सुधार किसने किया. टीमें बहुत प्रतिस्पर्धी हो जाती हैं! 🔥
नतीजे
हैकेथॉन (सॉफ़्टवेयर डेवलपमेंट इवेंट) का तरीका उनके लिए कारगर साबित हो रहा है.
- हैकथॉन के दौरान कई तरीकों को आज़माकर और Lighthouse की मदद से हर तरीके को मेज़र करके, परफ़ॉर्मेंस से जुड़ी समस्याओं का आसानी से पता लगाया जा सकता है.
- हैकथॉन के बाद, टीम को यह समझाना आसान हो जाता है कि प्रोडक्शन रिलीज़ के लिए, उन्हें किस ऑप्टिमाइज़ेशन को प्राथमिकता देनी चाहिए.
- यह गति की अहमियत को वकालत करने का एक असरदार तरीका भी है. इस सुविधा की मदद से, हर व्यक्ति यह समझ सकता है कि कोडिंग करने के तरीके और परफ़ॉर्मेंस के बीच क्या संबंध है.
इसकी एक अच्छी बात यह थी कि Recruit की कई अन्य इंजीनियरिंग टीमों ने इस तरीके में दिलचस्पी दिखाई. अब AirSHIFT की टीम, कंपनी में कई स्पीड हैकथॉन की सुविधा दे रही है.
खास जानकारी
इन ऑप्टिमाइज़ेशन पर काम करना, AirSHIFT के लिए आसान नहीं था. हालांकि, इसका फ़ायदा मिला. अब AirSHIFT, शिफ़्ट टेबल को औसतन 1.5 सेकंड में लोड कर रहा है. यह प्रोजेक्ट शुरू करने से पहले की परफ़ॉर्मेंस के मुकाबले छह गुना बेहतर है.
परफ़ॉर्मेंस ऑप्टिमाइज़ेशन लॉन्च होने के बाद, एक उपयोगकर्ता ने कहा:
शिफ़्ट टेबल को तेज़ी से लोड करने के लिए धन्यवाद. अब शिफ़्ट के हिसाब से काम को व्यवस्थित करना ज़्यादा आसान हो गया है.