JavaScript निष्पादन ऑप्टिमाइज़ करें

JavaScript अक्सर विज़ुअल में बदलाव ट्रिगर करता है. कभी-कभी, स्टाइल में बदलाव करके ऐसा किया जाता है. कभी-कभी, डेटा को खोजने या क्रम से लगाने जैसी गणनाओं की वजह से भी विज़ुअल में बदलाव होते हैं. गलत समय पर या लंबे समय तक चलने वाला JavaScript, परफ़ॉर्मेंस से जुड़ी समस्याओं की एक आम वजह है. आपको जहां भी हो सके, इसके असर को कम करने की कोशिश करनी चाहिए.

JavaScript अक्सर विज़ुअल में बदलाव ट्रिगर करता है. कभी-कभी, ऐसा सीधे तौर पर स्टाइल में बदलाव करके किया जाता है. कभी-कभी, डेटा को खोजने या क्रम से लगाने जैसी गणनाओं की वजह से, विज़ुअल में बदलाव होते हैं. परफ़ॉर्मेंस से जुड़ी समस्याओं की एक आम वजह यह है कि JavaScript को गलत समय पर या लंबे समय तक चलाया गया हो. आपको जहां भी हो सके, इसके असर को कम करने की कोशिश करनी चाहिए.

JavaScript की परफ़ॉर्मेंस की प्रोफ़ाइलिंग करना एक कला हो सकती है, क्योंकि आपका लिखा गया JavaScript कोड, असल में लागू किए गए कोड से बिलकुल अलग होता है. मॉडर्न ब्राउज़र, JIT कंपाइलर और सभी तरह के ऑप्टिमाइज़ेशन और ट्रिक का इस्तेमाल करके, आपको तेज़ी से कोड चलाने की सुविधा देते हैं. इससे कोड की डाइनैमिक में काफ़ी बदलाव होता है.

हालांकि, अपने ऐप्लिकेशन में JavaScript को बेहतर तरीके से इस्तेमाल करने के लिए, कुछ काम किए जा सकते हैं.

खास जानकारी

  • विज़ुअल अपडेट के लिए, setTimeout या setInterval का इस्तेमाल न करें. इसके बजाय, हमेशा requestAnimationFrame का इस्तेमाल करें.
  • लंबे समय तक चलने वाले JavaScript को मुख्य थ्रेड से वेब वर्कर पर ले जाएं.
  • कई फ़्रेम में डीओएम में बदलाव करने के लिए, माइक्रो-टास्क का इस्तेमाल करें.
  • JavaScript के असर का आकलन करने के लिए, Chrome DevTools की टाइमलाइन और JavaScript प्रोफ़ाइलर का इस्तेमाल करें.

विज़ुअल में बदलाव करने के लिए requestAnimationFrame का इस्तेमाल करें

जब स्क्रीन पर विज़ुअल में बदलाव हो रहे हों, तो आपको ब्राउज़र के लिए सही समय पर अपना काम करना होगा. यह समय, फ़्रेम की शुरुआत में होता है. requestAnimationFrame का इस्तेमाल करके ही यह पक्का किया जा सकता है कि आपका JavaScript, फ़्रेम की शुरुआत में चलेगा.

/**
    * If run as a requestAnimationFrame callback, this
    * will be run at the start of the frame.
    */
function updateScreen(time) {
    // Make visual updates here.
}

requestAnimationFrame(updateScreen);

ऐनिमेशन जैसे विज़ुअल बदलाव करने के लिए, फ़्रेमवर्क या सैंपल में setTimeout या setInterval का इस्तेमाल किया जा सकता है. हालांकि, इसकी समस्या यह है कि कॉलबैक फ़्रेम में किसी बिंदु पर चलेगा, शायद आखिर में. इससे अक्सर ऐसा हो सकता है कि हम कोई फ़्रेम न देख पाएं और वीडियो में रुकावट आ जाए.

setTimeout की वजह से ब्राउज़र को फ़्रेम नहीं मिल पा रहा है.

असल में, jQuery अपने animate व्यवहार के लिए setTimeout का इस्तेमाल करता था. इसे तीसरे वर्शन में, requestAnimationFrame का इस्तेमाल करने के लिए बदल दिया गया था. अगर jQuery का पुराना वर्शन इस्तेमाल किया जा रहा है, तो requestAnimationFrame का इस्तेमाल करने के लिए इसे पैच किया जा सकता है. हमारा सुझाव है कि ऐसा करें.

जटिलता कम करना या वेब वर्कर्स का इस्तेमाल करना

JavaScript, ब्राउज़र के मुख्य थ्रेड पर चलता है. यह स्टाइल कैलकुलेशन, लेआउट, और कई मामलों में पेन्ट के साथ-साथ चलता है. अगर आपका JavaScript लंबे समय तक चलता है, तो यह इन अन्य टास्क को ब्लॉक कर देगा. इससे, फ़्रेम छूटने की संभावना बढ़ जाती है.

आपको यह तय करना चाहिए कि JavaScript कब और कितनी देर तक चलेगा. उदाहरण के लिए, अगर स्क्रॉल करने जैसा कोई ऐनिमेशन चल रहा है, तो आपको अपने JavaScript को 3 से 4 मिलीसेकंड के आस-पास रखना चाहिए. इससे ज़्यादा समय लगने पर, आपका बहुत समय बर्बाद हो सकता है. अगर आपके पास समय है, तो वीडियो बनाने में ज़्यादा समय लिया जा सकता है.

कई मामलों में, पूरी तरह से कैलकुलेशन वाले काम को वेब वर्कर्स में ले जाया जा सकता है. उदाहरण के लिए, अगर उसे DOM ऐक्सेस की ज़रूरत नहीं है. डेटा में बदलाव करने या डेटा को एक से दूसरी जगह ले जाने के लिए, अक्सर इस मॉडल का इस्तेमाल किया जाता है. जैसे, डेटा को क्रम से लगाना या खोजना. इसके अलावा, डेटा लोड करने और मॉडल जनरेट करने के लिए भी इस मॉडल का इस्तेमाल किया जाता है.

var dataSortWorker = new Worker("sort-worker.js");
dataSortWorker.postMesssage(dataToSort);

// The main thread is now free to continue working on other things...

dataSortWorker.addEventListener('message', function(evt) {
    var sortedData = evt.data;
    // Update data on screen...
});

सभी काम इस मॉडल में फ़िट नहीं हो सकते: वेब वर्कर के पास डीओएम का ऐक्सेस नहीं होता. अगर आपका काम मुख्य थ्रेड पर होना चाहिए, तो एक साथ कई काम करने का तरीका अपनाएं. इसमें, बड़े टास्क को छोटे-छोटे टास्क में बांटा जाता है. हर टास्क को पूरा करने में कुछ मिलीसेकंड से ज़्यादा समय नहीं लगता. साथ ही, हर फ़्रेम में requestAnimationFrame हैंडलर के अंदर चलाया जाता है.

इस तरीके से, यूज़र एक्सपीरियंस (UX) और यूज़र इंटरफ़ेस (यूआई) पर असर पड़ता है. इसलिए, आपको यह पक्का करना होगा कि उपयोगकर्ता को पता हो कि कोई टास्क प्रोसेस किया जा रहा है. इसके लिए, प्रोग्रेस या गतिविधि के इंडिकेटर का इस्तेमाल करें. किसी भी मामले में, इस तरीके से आपके ऐप्लिकेशन की मुख्य थ्रेड खाली रहेगी. इससे, उपयोगकर्ता के इंटरैक्शन के लिए ऐप्लिकेशन को रिस्पॉन्सिव बनाए रखने में मदद मिलेगी.

अपने JavaScript के “फ़्रेम टैक्स” के बारे में जानें

किसी फ़्रेमवर्क, लाइब्रेरी या अपने कोड का आकलन करते समय, यह आकलन करना ज़रूरी है कि हर फ़्रेम के हिसाब से JavaScript कोड को चलाने में कितनी लागत आती है. यह तब ज़्यादा ज़रूरी होता है, जब ऐनिमेशन से जुड़ा ऐसा काम किया जा रहा हो जिससे परफ़ॉर्मेंस पर असर पड़ता हो. जैसे, ट्रांज़िशन या स्क्रोल करना.

Chrome DevTools के परफ़ॉर्मेंस पैनल का इस्तेमाल करके, JavaScript की लागत को मेज़र करने का सबसे अच्छा तरीका है. आम तौर पर, आपको इस तरह के लो-लेवल रिकॉर्ड मिलते हैं:

Chrome DevTools में परफ़ॉर्मेंस रिकॉर्डिंग

मुख्य सेक्शन में, JavaScript कॉल का फ़्लेम चार्ट दिखता है. इससे, यह विश्लेषण किया जा सकता है कि किन फ़ंक्शन को कॉल किया गया और हर फ़ंक्शन को कॉल करने में कितना समय लगा.

इस जानकारी की मदद से, अपने ऐप्लिकेशन पर JavaScript के असर का आकलन किया जा सकता है. साथ ही, उन हॉटस्पॉट का पता लगाया जा सकता है जहां फ़ंक्शन को लागू होने में ज़्यादा समय लग रहा है और उन्हें ठीक किया जा सकता है. जैसा कि पहले बताया गया है, आपको लंबे समय तक चलने वाले JavaScript को हटाना चाहिए. अगर ऐसा नहीं किया जा सकता, तो उसे वेब वर्कर्स पर ले जाएं. इससे मुख्य थ्रेड खाली हो जाएगी और वह अन्य टास्क पर काम कर पाएगी.

परफ़ॉर्मेंस पैनल का इस्तेमाल करने का तरीका जानने के लिए, रनटाइम परफ़ॉर्मेंस का विश्लेषण करना शुरू करें लेख पढ़ें.

अपने JavaScript को माइक्रो-ऑप्टिमाइज़ करने से बचें

यह जानना दिलचस्प हो सकता है कि ब्राउज़र किसी चीज़ के एक वर्शन को किसी दूसरी चीज़ के मुकाबले 100 गुना तेज़ी से लागू कर सकता है. जैसे, किसी एलिमेंट के offsetTop का अनुरोध करना, getBoundingClientRect() का हिसाब लगाने से ज़्यादा तेज़ है. हालांकि, यह ज़्यादातर मामलों में सच होता है कि आपको हर फ़्रेम में, इन जैसे फ़ंक्शन को सिर्फ़ कुछ ही बार कॉल करना होगा. इसलिए, आम तौर पर JavaScript की परफ़ॉर्मेंस के इस पहलू पर फ़ोकस करना बेकार है. आम तौर पर, आपको सिर्फ़ कुछ मिलीसेकंड की बचत होगी.

अगर कोई गेम या ऐसा ऐप्लिकेशन बनाया जा रहा है जिसमें बहुत ज़्यादा कैलकुलेशन की ज़रूरत होती है, तो हो सकता है कि आप इस दिशा-निर्देश के अपवाद हों. ऐसा इसलिए, क्योंकि आम तौर पर आपको एक फ़्रेम में बहुत ज़्यादा कैलकुलेशन करने होते हैं और ऐसे में, हर चीज़ मददगार होती है.

कम शब्दों में, आपको माइक्रो-ऑप्टिमाइज़ेशन से सावधान रहना चाहिए, क्योंकि आम तौर पर ये आपके बनाए जा रहे ऐप्लिकेशन के हिसाब से काम नहीं करेंगे.