साइटों को JavaScript पर ज़्यादा निर्भर होने की वजह से, हम कभी-कभी इनके लिए पैसे चुकाते हैं. ये ऐसे तरीके होते हैं जिन्हें पढ़ना हमारे लिए मुश्किल होता है. इस लेख में, हम बताएंगे कि अगर आपको मोबाइल डिवाइस पर अपनी साइट को तेज़ी से लोड करना है और उससे इंटरैक्ट करना है, तो आपको यहां दिए गए अनुपात से मदद क्यों मिल सकती है. कम JavaScript डिलीवर करने का मतलब है, नेटवर्क ट्रांसमिशन में कम समय, कोड को डीकंप्रेस करने में कम समय खर्च, और JavaScript को पार्स और कंपाइल करने में कम समय.
नेटवर्क
जब ज़्यादातर डेवलपर JavaScript की लागत के बारे में सोचते हैं, तो वे इसके बारे में डाउनलोड और लागू करने की लागत को ध्यान में रखते हैं. वायर के ऊपर JavaScript के ज़्यादा बाइट भेजने से, उपयोगकर्ता के कनेक्शन को प्रोसेस करने में ज़्यादा समय लगता है.
इससे समस्या हो सकती है, क्योंकि हो सकता है कि उपयोगकर्ता के पास प्रभावी नेटवर्क कनेक्शन प्रकार असल में 3G, 4G या वाई-फ़ाई न हो. कॉफ़ी शॉप वाई-फ़ाई पर हो सकते हैं, लेकिन 2G स्पीड वाले मोबाइल हॉटस्पॉट से कनेक्ट हो सकते हैं.
इन तरीकों की मदद से, JavaScript की नेटवर्क ट्रांसफ़र लागत को कम किया जा सकता है:
- सिर्फ़ वही कोड भेजना जो उपयोगकर्ता को चाहिए.
- कोड-स्प्लिटिंग का इस्तेमाल करके, अपनी JavaScript को अलग-अलग हिस्सों में बांटें. इससे यह तय किया जा सकता है कि कौनसी चीज़ अहम है और कौनसी नहीं. मॉड्यूल बंडलर, जैसे कि webpack कोड-स्प्लिटिंग की सुविधा देते हैं.
- ऐसे कोड में धीरे से लोड होना जो गैर-ज़रूरी है.
- काट-छांट करना
- ES5 कोड को कम से कम करने के लिए, UglifyJS का इस्तेमाल करें.
- ES2015+ को छोटा करने के लिए, babel-minify या uglify-es का इस्तेमाल करें.
- कंप्रेस करना
- इस्तेमाल न होने वाले कोड को हटाना.
- DevTool कोड कवरेज की मदद से, उन कोड की पहचान करें जिन्हें हटाया जा सकता है या लेज़ी लोड किया जा सकता है.
- मॉडर्न ब्राउज़र में पहले से मौजूद ट्रांसपिलिंग सुविधाओं से बचने के लिए, babel-preset-env और ब्राउज़रलिस्ट का इस्तेमाल करें. बेहतर डेवलपर को अपने वेबपैक बंडल का सावधानी से विश्लेषण करने से, ग़ैर-ज़रूरी डिपेंडेंसी कम करने के अवसरों की पहचान करने में मदद मिल सकती है.
- कोड को स्ट्रिप करने के लिए, ट्री-शेकिंग, क्लोज़र कॉम्पिलर के बेहतर ऑप्टिमाइज़ेशन और लाइब्रेरी lodash-babel-plugin या वेबपैक का ContextReplacementPlugin जैसे कि Moment.js जैसी लाइब्रेरी के प्लगिन देखें.
- नेटवर्क ट्रिप कम करने के लिए कोड कैश मेमोरी में सेव करना.
- यह पक्का करने के लिए कि ब्राउज़र रिस्पॉन्स को सही तरीके से कैश मेमोरी में सेव करे, एचटीटीपी कैश मेमोरी का इस्तेमाल करें. स्क्रिप्ट (मैक्स-एज) के लिए सबसे सही लाइफ़टाइम तय करें और पुष्टि करने वाले टोकन (ETag) उपलब्ध कराएं, ताकि बिना बदलाव की गई बाइट ट्रांसफ़र न हों.
- सर्विस वर्कर कैश मेमोरी में सेव करने से, आपके ऐप्लिकेशन नेटवर्क को अपनी ज़रूरत के मुताबिक ढाला जा सकता है. साथ ही, इससे आपको V8 के कोड कैश जैसी सुविधाओं का तुरंत ऐक्सेस मिलता है.
- जिन संसाधनों में कोई बदलाव नहीं हुआ है उन्हें फिर से फ़ेच करने से बचने के लिए, लंबे समय तक कैश मेमोरी का इस्तेमाल करें. अगर Webpack का इस्तेमाल किया जा रहा है, तो फ़ाइल नाम हैशिंग देखें.
पार्स/कंपाइल करें
डाउनलोड होने के बाद, JavaScript की सबसे ज़्यादा लागत में से एक वह समय होता है, जब JS इंजन इस कोड को पार्स/कंपाइल करता है. Chrome DevTool में, पार्स और कंपाइल करने में सेट किए गए, परफ़ॉर्मेंस पैनल में पीले रंग की "स्क्रिप्टिंग" समय का हिस्सा होता है.
बॉटम-अप और कॉल ट्री टैब आपको सटीक पार्स/कंपाइल समय दिखाते हैं:
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-cfd35a90562dd.png?authuser=6&hl=hi)
लेकिन, इससे फ़र्क क्यों पड़ता है?
कोड को पार्स/कंपोज़ करने में लंबा समय खर्च करने से, उपयोगकर्ता के आपकी साइट से इंटरैक्ट करने में काफ़ी समय लग सकता है. जितना ज़्यादा JavaScript भेजा जाएगा, आपकी साइट के इंटरैक्टिव होने से पहले उसे पार्स और कंपाइल करने में उतना ही ज़्यादा समय लगेगा.
बाइट-दर-बाइट, ब्राउज़र के लिए JavaScript को प्रोसेस करना ज़्यादा महंगा है, जो उसके बराबर के साइज़ की इमेज या वेब फ़ॉन्ट की तुलना में ज़्यादा महंगा है — टॉम डेल
JavaScript की तुलना में, समान साइज़ की इमेज को प्रोसेस करने में बहुत लागत आती है (फिर भी उन्हें डिकोड करना पड़ता है!) लेकिन औसतन मोबाइल हार्डवेयर में, JS से किसी पेज की इंटरैक्टिविटी पर बुरा असर पड़ सकता है.
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-e3dc86ddc7603.png?authuser=6&hl=hi)
जब हम पार्स और कंपाइल करने की धीमी रफ़्तार की बात करते हैं; संदर्भ अहम होता है — यहां हम औसत मोबाइल फ़ोन की बात कर रहे हैं. औसत उपयोगकर्ताओं के पास धीमे सीपीयू और जीपीयू वाले फ़ोन हो सकते हैं, लेकिन L2/L3 कैश मेमोरी नहीं होती और मेमोरी भी सीमित हो सकती है.
नेटवर्क की सुविधाएं और डिवाइस की सुविधाएं हमेशा एक जैसी नहीं होती हैं. यह ज़रूरी नहीं है कि बेहतरीन फ़ाइबर कनेक्शन वाले उपयोगकर्ता के पास डिवाइस पर भेजे गए JavaScript को पार्स करने और उसका आकलन करने के लिए सबसे अच्छा सीपीयू (CPU) क्यों न हो. यह भी रिवर्स तरीके से सच है... एक खराब नेटवर्क कनेक्शन, लेकिन बहुत तेज़ तेज़ सीपीयू. — क्रिस्टोफ़र बैक्सटर, LinkedIn
नीचे हम सस्ते और महंगे हार्डवेयर के लिए, ~1 एमबी की डिकंप्रेस किए गए (आसान) JavaScript को पार्स करने की कीमत देख सकते हैं. बाज़ार में सबसे तेज़ फ़ोन और औसत फ़ोन के बीच, कोड को पार्स/ककल करने में दो से पांच गुना का अंतर होता है.
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-52af247f207f5.png?authuser=6&hl=hi)
CNN.com जैसी किसी साइट पर क्या होगा?
एक महंगे iPhone 8 पर औसत फ़ोन (Moto G4) के लिए ~13s की तुलना में, CNN के JS को पार्स/कंप करने में सिर्फ़ ~4 सेकंड लगते हैं. इससे इस बात पर काफ़ी असर पड़ सकता है कि उपयोगकर्ता इस साइट से कितनी जल्दी पूरी तरह इंटरैक्ट कर सकते हैं.
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-7cafa788a7bdf.png?authuser=6&hl=hi)
इससे सिर्फ़ आपकी जेब में रखे फ़ोन के बजाय, औसत हार्डवेयर (जैसे कि Moto G4) पर टेस्ट करने की अहमियत को हाइलाइट किया जाता है. हालांकि, संदर्भ मायने रखता है: अपने उपयोगकर्ताओं के डिवाइस और नेटवर्क की स्थितियों के हिसाब से ऑप्टिमाइज़ करें.
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-6de3a79335e9b.png?authuser=6&hl=hi)
क्या हम वाकई बहुत ज़्यादा JavaScript भेज रहे हैं? शायद, गड़बड़ी है :)
मोबाइल पर JavaScript की स्थिति का विश्लेषण करने के लिए, एचटीटीपी संग्रह (टॉप 5 लाख साइटें) का इस्तेमाल करके, हम देख सकते हैं कि 50% साइटों को इंटरैक्टिव होने में 14 सेकंड से ज़्यादा समय लगता है. ये साइटें JS को बस पार्स और कंपाइल करने में चार सेकंड तक का समय लेती हैं.
JS और अन्य रिसॉर्स को फ़ेच करने और प्रोसेस करने में लगने वाले समय पर ध्यान दें. इस बात में कोई हैरानी की बात नहीं है कि उपयोगकर्ताओं को लगता है कि पेज इस्तेमाल के लिए तैयार हैं और इससे पहले उन्हें कुछ देर इंतज़ार करना पड़ सकता है. हम यहां निश्चित तौर पर बेहतर कर सकते हैं.
अपने पेजों से गै़र-ज़रूरी JavaScript को हटाने से ट्रांसमिशन का समय, सीपीयू पर आधारित पार्स करने और कंपाइल करने, और संभावित मेमोरी ओवरहेड कम करने में मदद मिल सकती है. इससे आपके पेजों को तेज़ी से इंटरैक्टिव बनाने में भी मदद मिलती है.
एक्ज़ीक्यूशन का समय
यह सिर्फ़ पार्स और कंपाइल करने का काम नहीं है, जिसकी एक लागत हो सकती है. JavaScript को एक्ज़ीक्यूट करना (पार्स या कंपाइल किए जाने के बाद कोड को चलाना), उन कार्रवाइयों में से एक है जो मुख्य थ्रेड पर होनी चाहिए. एक्ज़ीक्यूशन की अवधि ज़्यादा होने से यह पता चल सकता है कि कोई उपयोगकर्ता कितनी जल्दी आपकी साइट से इंटरैक्ट कर सकता है.
अगर स्क्रिप्ट 50 मि॰से॰ से ज़्यादा समय तक चलती है, तो JS को डाउनलोड, कंपाइल, और एक्ज़ीक्यूट करने में पूरा समय लग सकता है. — एलेक्स रसेल
इसे ठीक करने के लिए, JavaScript को छोटे हिस्सों में होने से फ़ायदा मिलता है, ताकि मुख्य थ्रेड को लॉक होने से बचाया जा सके. यह एक्सप्लोर करें कि एक्ज़ीक्यूशन के दौरान होने वाले काम को कम किया जा सकता है या नहीं.
अन्य लागतें
JavaScript, पेज की परफ़ॉर्मेंस पर दूसरे तरीकों से असर डाल सकता है:
- मेमोरी. जीसी (ट्रैश कलेक्शन) की वजह से, पेज बार-बार जैंक या रुक सकते हैं. जब कोई ब्राउज़र मेमोरी को फिर से हासिल करता है, तो JS एक्ज़ीक्यूशन रोक दिया जाता है. इससे बार-बार कचरा इकट्ठा करने वाला ब्राउज़र, एक्ज़ीक्यूशन को जल्दी-जल्दी रोक सकता है. मेमोरी लीक से बचें और बार-बार जीसी रोकने से बचें, ताकि पेजों को जैंक फ़्री रखा जा सके.
- रनटाइम के दौरान, लंबे समय तक चलने वाले JavaScript से मुख्य थ्रेड काम न करने वाले पेज ब्लॉक हो सकते हैं. काम को छोटे-छोटे हिस्सों में (शेड्यूल करने के लिए
requestAnimationFrame()
याrequestIdleCallback()
का इस्तेमाल करके) करने से रिस्पॉन्स मिलने से जुड़ी समस्याएं कम हो सकती हैं. इससे इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) को बेहतर बनाया जा सकता है.
JavaScript डिलीवरी की लागत कम करने के पैटर्न
जब JavaScript के लिए पार्स/कंपाइल और नेटवर्क ट्रांसमिशन समय को धीमा रखने की कोशिश की जाती है, तब कुछ ऐसे पैटर्न होते हैं जो रूट-आधारित चंकिंग या PRPL जैसे कामों में मदद कर सकते हैं.
पीआरपीएल
PRPL (पुश, रेंडर, प्री-कैश, लेज़ी-लोड) एक ऐसा पैटर्न है जो कोड को ज़्यादा बारीकी से स्प्लिट और कैश मेमोरी में सेव करके, इंटरैक्टिविटी के लिए ऑप्टिमाइज़ करता है:
आइए, देखते हैं कि इसका क्या असर हो सकता है.
हम लोकप्रिय मोबाइल साइटों और प्रोग्रेसिव वेब ऐप्लिकेशन के लोड होने में लगने वाले समय का विश्लेषण करते हैं. इसके लिए, हम V8 के रनटाइम कॉल के आंकड़ों का इस्तेमाल करते हैं. जैसा कि हम देख सकते हैं, पार्स टाइम (नारंगी रंग में दिखाया गया) उस जगह का एक अहम हिस्सा है जहां इनमें से ज़्यादातर साइटें अपना समय बिताते हैं:
PRPL का इस्तेमाल करने वाली Wego साइट, अपने रूट के लिए पार्स टाइम को कम बनाए रखती है, जिससे यह बहुत तेज़ी से इंटरैक्टिव हो जाती है. ऊपर दी गई कई साइटों ने अपनी JS लागत कम करने के लिए, कोड को अलग-अलग करने और परफ़ॉर्मेंस बजट का इस्तेमाल किया.
प्रोग्रेसिव बूटस्ट्रैपिंग
कई साइटें, इंटरैक्टिविटी के आधार पर कॉन्टेंट दिखने की सेटिंग को ऑप्टिमाइज़ करती हैं. बड़े JavaScript बंडल होने पर तेज़ी से कॉन्टेंट लोड करने के लिए, डेवलपर कभी-कभी सर्वर-साइड रेंडरिंग का इस्तेमाल करते हैं. इसके बाद, JavaScript को फ़ेच होने के बाद, इवेंट हैंडलर अटैच करने के लिए इसे "अपग्रेड" करें.
ध्यान रखें — इसमें अलग-अलग शुल्क होते हैं. 1) आम तौर पर, बड़ा एचटीएमएल रिस्पॉन्स भेजा जाता है, जिससे हमारी इंटरैक्टिविटी बढ़ सकती है, 2) इससे उपयोगकर्ता को किसी अनचाही घाटी में वापस भेज दिया जाता है. इसका आधा हिस्सा तब तक इंटरैक्टिव नहीं हो पाता, जब तक JavaScript की प्रोसेस पूरी नहीं हो जाती.
प्रोग्रेसिव बूटस्ट्रैपिंग एक बेहतर तरीका हो सकता है. एक सबसे कम काम करने वाला पेज भेजें (जिसमें मौजूदा रूट के लिए सिर्फ़ ज़रूरी HTML/JS/सीएसएस शामिल हों). जैसे-जैसे ज़्यादा संसाधन मिलते हैं, ऐप्लिकेशन लेज़ी-लोड और ज़्यादा सुविधाओं को अनलॉक कर सकता है.
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-bc9d1b36573cd.png?authuser=6&hl=hi)
व्यू में दिख रहे कोड के अनुपात में कोड लोड होता है. PRPL और प्रोग्रेसिव बूटस्ट्रैपिंग ऐसे पैटर्न हैं जिनकी मदद से इस काम को पूरा किया जा सकता है.
मीटिंग में सामने आए नतीजे
लो एंड नेटवर्क के लिए ट्रांसमिशन का साइज़ बहुत अहम होता है. पार्स होने में लगने वाला समय, सीपीयू से जुड़े डिवाइसों के लिए अहम है. इन छोटी बातों को अहमियत देना.
टीमों ने अपने JavaScript ट्रांसमिशन और पार्स/कंपाइल समय को कम रखने के लिए, सख्त परफ़ॉर्मेंस बजट को अपनाने में सफलता पाई. एलेक्स रसेल का लेख "कैन यू अफ़र्ड इट?: मोबाइल के लिए बजट के बारे में दिशा-निर्देश के लिए" रीयल-वर्ल्ड वेब परफ़ॉर्मेंस बजट देखें.
![ALT_TEXT_HERE](https://web.dev/static/articles/optimizing-content-efficiency-javascript-startup-optimization/image/alttexthere-72d5f9f9722e.png?authuser=6&hl=hi)
अगर आपकी साइट मोबाइल डिवाइसों को टारगेट करती है, तो अपनी साइट के लिए सबसे सही हार्डवेयर इस्तेमाल करें. JavaScript पार्स करने या कंपाइल करने का समय कम रखें. साथ ही, परफ़ॉर्मेंस बजट का इस्तेमाल करें, ताकि आपकी टीम अपनी JavaScript लागत पर नज़र रख सके.
ज़्यादा जानें
- Chrome डेवलपर समिट 2017 - आधुनिक लोडिंग के सबसे सही तरीके
- JavaScript शुरू करने की परफ़ॉर्मेंस
- वेब परफ़ॉर्मेंस की समस्या को हल करना — नोलन लॉसन
- क्या आप वहन किए जा सकते हैं? असल दुनिया की परफ़ॉर्मेंस बजट — एलेक्स रसेल
- वेब फ़्रेमवर्क और लाइब्रेरी का आकलन करना — क्रिस्टोफ़र बैक्सटर
- कंप्रेस करने के लिए, Cloudflare के Brotli के साथ प्रयोग करने के नतीजे (ध्यान दें कि बेहतर क्वालिटी वाला डाइनैमिक Brotli हो सकता है. इससे, शुरुआती पेज के रेंडर होने में देर हो सकती है. इसलिए, ध्यान से आकलन करें. ऐसा हो सकता है कि आप इसके बजाय स्टैटिक रूप से कंप्रेस करना चाहें.)
- परफ़ॉर्मेंस फ़्यूचर — सैम सैकोन