तीसरे पक्ष का JavaScript ऑप्टिमाइज़ करना

तीसरे पक्ष की स्क्रिप्ट, परफ़ॉर्मेंस पर असर डालती हैं. इसलिए, यह ज़रूरी है कि आप समय-समय पर उनकी जांच करें और उन्हें लोड करने की बेहतर तकनीकों का इस्तेमाल करें. इस कोडलैब से आपको तीसरे पक्ष के संसाधनों को लोड करने के तरीके को ऑप्टिमाइज़ करने का तरीका पता चलता है. इसमें इन तकनीकों के बारे में बताया गया है:

  • स्क्रिप्ट लोड होने में देरी हो रही है

  • गैर-ज़रूरी संसाधन की लेज़ी लोडिंग

  • ज़रूरी ऑरिजिन से पहले से कनेक्ट किया जा रहा है

सैंपल के तौर पर शामिल किए गए ऐप्लिकेशन में, एक सामान्य वेब पेज मिलता है. इस पेज में, तीसरे पक्ष के सोर्स से तीन सुविधाएं मिलती हैं:

  • वीडियो एम्बेड

  • लाइन ग्राफ़ को रेंडर करने के लिए डेटा विज़ुअलाइज़ेशन लाइब्रेरी

  • सोशल मीडिया पर शेयर करने का विजेट

पेज का स्क्रीनशॉट, जिसमें तीसरे पक्ष के संसाधनों को हाइलाइट किया गया है.
सैंपल ऐप्लिकेशन में तीसरे पक्ष के संसाधन.

आपको सबसे पहले ऐप्लिकेशन की परफ़ॉर्मेंस का आकलन करना होगा. इसके बाद, हर तकनीक का इस्तेमाल करके, ऐप्लिकेशन की परफ़ॉर्मेंस के अलग-अलग पहलुओं को बेहतर करना होगा.

परफ़ॉर्मेंस का आकलन करना

पहले, फ़ुलस्क्रीन व्यू में ऐप्लिकेशन का नमूना खोलें:

  1. प्रोजेक्ट में बदलाव करने के लिए, बदलाव करने के लिए रीमिक्स करें पर क्लिक करें.
  2. साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन.

बेसलाइन परफ़ॉर्मेंस तय करने के लिए, पेज पर Lighthouse परफ़ॉर्मेंस ऑडिट करें:

  1. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  2. Lighthouse टैब पर क्लिक करें.
  3. मोबाइल पर क्लिक करें.
  4. परफ़ॉर्मेंस चेकबॉक्स को चुनें. (ऑडिट सेक्शन में बाकी चेकबॉक्स हटाए जा सकते हैं.)
  5. सिम्युलेटेड फ़ास्ट 3G, 4x सीपीयू स्लोडाउन पर क्लिक करें.
  6. स्टोरेज खाली करें चेकबॉक्स को चुनें.
  7. ऑडिट चलाएं पर क्लिक करें.

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

लाइटहाउस ऑडिट का स्क्रीनशॉट, जिसमें 2.4 सेकंड एफ़सीपी और दो अवसर दिखाए गए हैं: रेंडर ब्लॉक करने वाले संसाधनों को हटाएं और ज़रूरी ऑरिजिन से प्रीकनेक्ट करें.

तीसरे पक्ष की JavaScript को कुछ समय के लिए रोकें

रेंडर ब्लॉक करने वाले संसाधनों को हटाएं ऑडिट ने यह पता लगाया है कि d3js.org से आने वाली स्क्रिप्ट को रोककर, कुछ समय बचाया जा सकता है:

रेंडर ब्लॉक करने वाले रिसॉर्स के ऑडिट को हटाने का स्क्रीनशॉट, जिसमें d3.v3.min.js स्क्रिप्ट हाइलाइट की गई है.

D3.js डेटा विज़ुअलाइज़ेशन बनाने के लिए एक JavaScript लाइब्रेरी है. सैंपल ऐप्लिकेशन में मौजूद script.js फ़ाइल, SVG लाइन चार्ट बनाने और उसे पेज में जोड़ने के लिए, D3 यूटिलिटी फ़ंक्शन का इस्तेमाल करती है. यहां कार्रवाइयों का क्रम अहम है: दस्तावेज़ को पार्स करने और D3 लाइब्रेरी लोड होने के बाद, script.js चलना चाहिए. इसलिए, इसे index.html में क्लोज़िंग </body> टैग से ठीक पहले शामिल किया गया है.

हालांकि, D3 स्क्रिप्ट को पेज के <head> में शामिल किया जाता है, जो बाकी दस्तावेज़ को पार्स करने से रोकता है:

हेडर में हाइलाइट किए गए स्क्रिप्ट टैग के साथ index.html का स्क्रीनशॉट.

स्क्रिप्ट टैग में दो मैजिक एट्रिब्यूट जोड़ने पर, पार्सर को अनब्लॉक किया जा सकता है:

  • async यह पक्का करता है कि स्क्रिप्ट बैकग्राउंड में डाउनलोड हो जाएं और डाउनलोड पूरा होने के बाद, पहली बार लागू हो जाएं.

  • defer यह पक्का करता है कि स्क्रिप्ट बैकग्राउंड में डाउनलोड हों और पार्स करने के बाद काम करती हों.

यह चार्ट पूरे पेज के लिए बहुत ज़रूरी नहीं है. ऐसा हो सकता है कि यह चार्ट, पेज के निचले हिस्से के नीचे हो. इसलिए, defer का इस्तेमाल करके यह पक्का करें कि पार्सर को ब्लॉक न किया जा रहा हो.

पहला चरण: defer एट्रिब्यूट की मदद से, स्क्रिप्ट को एसिंक्रोनस रूप से लोड करें

index.html की लाइन 17 पर, <script> एलिमेंट में defer एट्रिब्यूट जोड़ें:

<script src="https://d3js.org/d3.v3.min.js" defer></script>

दूसरा चरण: पक्का करना कि कार्रवाइयां सही क्रम में हों

अब जबकि D3 को टाला गया है, तो D3 के तैयार होने से पहले script.js चलेगा, जिससे गड़बड़ी होगी.

defer एट्रिब्यूट वाली स्क्रिप्ट उसी क्रम में चलती हैं जिस क्रम में उन्हें तय किया गया था. यह पक्का करने के लिए कि D3 के तैयार होने के बाद script.js एक्ज़ीक्यूट हो जाए, इसमें defer जोड़ें और इसे D3 <script> एलिमेंट के ठीक बाद दस्तावेज़ के <head> तक ले जाएं. अब यह पार्सर को ब्लॉक नहीं करता और डाउनलोड जल्द ही शुरू हो जाता है.

<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>

तीसरे पक्ष के संसाधन को लेज़ी-लोड करें

वेबसाइट में फ़ोल्ड के नीचे मौजूद सभी रिसॉर्स, लेज़ी लोडिंग के हिसाब से सही होते हैं.

सैंपल ऐप्लिकेशन में, iframe में एम्बेड किया गया YouTube वीडियो मौजूद है. यह देखने के लिए कि पेज कितने अनुरोध करता है और कौनसे अनुरोध एम्बेड किए गए YouTube iframe से आते हैं:

  1. साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन.
  2. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  3. नेटवर्क टैब पर क्लिक करें.
  4. कैश मेमोरी बंद करें चेकबॉक्स चुनें.
  5. थ्रॉटलिंग ड्रॉपडाउन मेन्यू में, फ़ास्ट 3G चुनें.
  6. पेज को फिर से लोड करें.

DevTools नेटवर्क पैनल का स्क्रीनशॉट.

नेटवर्क पैनल से पता चलता है कि इस पेज ने कुल 28 अनुरोध किए और करीब एक एमबी कंप्रेस किए गए संसाधन ट्रांसफ़र किए.

YouTube iframe की ओर से किए गए अनुरोधों की पहचान करने के लिए, शुरुआत करने वाले कॉलम में वीडियो आईडी 6lfaiXM6waw देखें. डोमेन के हिसाब से सभी अनुरोधों को एक साथ ग्रुप करने के लिए:

  • नेटवर्क पैनल में, कॉलम के टाइटल पर राइट क्लिक करें.

  • ड्रॉपडाउन मेन्यू में, डोमेन कॉलम चुनें.

  • डोमेन के हिसाब से अनुरोधों को क्रम से लगाने के लिए, डोमेन कॉलम के टाइटल पर क्लिक करें.

नए क्रम से पता चलता है कि Google डोमेन के लिए कुछ और अनुरोध हैं. कुल मिलाकर, YouTube iframe स्क्रिप्ट, स्टाइलशीट, इमेज, और फ़ॉन्ट के लिए 14 अनुरोध करता है. हालांकि, जब तक उपयोगकर्ता वीडियो चलाने के लिए नीचे की ओर स्क्रोल नहीं करते, तब तक उन्हें उन सभी ऐसेट की ज़रूरत नहीं होती.

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

लेज़ी लोडिंग को लागू करने का एक तरीका है, इंटरसेक्शन ऑब्ज़र्वर का इस्तेमाल करना. यह एक ब्राउज़र एपीआई है जो किसी एलिमेंट के ब्राउज़र के व्यूपोर्ट में शामिल होने या उससे बाहर निकलने पर, आपको इसकी सूचना देता है.

पहला चरण: वीडियो को शुरुआत में लोड होने से रोकना

वीडियो iframe को लेज़ी-लोड करने के लिए, पहले आपको इसे सामान्य तरीके से लोड होने से रोकना होगा. ऐसा करने के लिए, src एट्रिब्यूट को data-src एट्रिब्यूट से बदलें, ताकि वीडियो के यूआरएल की जानकारी दी जा सके:

<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

data-src एक डेटा एट्रिब्यूट है. इससे स्टैंडर्ड एचटीएमएल एलिमेंट पर ज़्यादा जानकारी स्टोर की जा सकती है. डेटा एट्रिब्यूट को कोई भी नाम दिया जा सकता है. हालांकि, यह ज़रूरी है कि वह "data-" से शुरू हो.

बिना src वाला iframe लोड नहीं होता.

दूसरा चरण: वीडियो को लेज़ी-लोड करने के लिए, इंटरसेक्शन ऑब्ज़र्वर का इस्तेमाल करें

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

शुरू करने के लिए, एक नई फ़ाइल बनाएं और उसे lazy-load.js नाम दें:

  • नई फ़ाइल पर क्लिक करें और उसे एक नाम दें.
  • Add this File पर क्लिक करें.

अपने दस्तावेज़ के हेड में स्क्रिप्ट टैग जोड़ें:

 <script src="/lazy-load.js" defer></script>

lazy-load.js में, एक नया IntersectionObserver बनाएं और उसे चलाने के लिए, कॉलबैक फ़ंक्शन पास करें:

// create a new Intersection Observer
let observer = new IntersectionObserver(callback);

अब observer को देखने के लिए टारगेट एलिमेंट (इस मामले में वीडियो iframe) दें. इसके लिए, इसे observe तरीके में आर्ग्युमेंट के तौर पर पास करें:

// the element that you want to watch
const element = document.querySelector('iframe');

// register the element with the observe method
observer.observe(element);

callback को IntersectionObserverEntry ऑब्जेक्ट और IntersectionObserver ऑब्जेक्ट की सूची मिलती है. हर एंट्री में एक target एलिमेंट और प्रॉपर्टी होती हैं, जो उसके डाइमेंशन, पोज़िशन, उसके व्यूपोर्ट में शामिल होने का समय वगैरह की जानकारी देती हैं. IntersectionObserverEntry की एक प्रॉपर्टी isIntersecting है—यह एक बूलियन वैल्यू होती है, जो किसी एलिमेंट के व्यूपोर्ट में आने पर, true के बराबर होती है.

इस उदाहरण में, target, iframe है. जब target व्यूपोर्ट में आता है, तो isIntersecting का मान true होता है. इसे काम करने के लिए देखने के लिए, callback को नीचे दिए गए फ़ंक्शन से बदलें:

let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
    entries.forEach(entry => {
      console.log(entry.target);
      console.log(entry.isIntersecting);
    });
  });
  1. साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन.
  2. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  3. कंसोल टैब पर क्लिक करें.

ऊपर और नीचे स्क्रोल करके देखें. आपको isIntersecting की वैल्यू में बदलाव और कंसोल में लॉग किया गया टारगेट एलिमेंट दिखेगा.

जब उपयोगकर्ता स्क्रोल करके अपनी जगह पर पहुंच जाए, तब वीडियो को लोड करने के लिए, loadElement फ़ंक्शन चलाने की शर्त के तौर पर isIntersecting का इस्तेमाल करें. इससे iframe एलिमेंट के data-src से वैल्यू मिलती है और उसे iframe एलिमेंट के src एट्रिब्यूट के तौर पर सेट किया जाता है. उस बदलाव से, वीडियो लोड होना शुरू हो जाता है. इसके बाद, वीडियो लोड होने के बाद, टारगेट एलिमेंट को देखना बंद करने के लिए, unobserve तरीके को observer पर कॉल करें:

let observer = new IntersectionObserver(function (entries, observer) {
  entries.forEach(entry => {
    console.log(entry.target);
    console.log(entry.isIntersecting);
  });
});
    if (entry.isIntersecting) {
      // do this when the element enters the viewport
      loadElement(entry.target);
      // stop watching
      observer.unobserve(entry.target);
    }
  });
});

function loadElement(element) {
  const src = element.getAttribute('data-src');
  element.src = src;
}

तीसरा चरण: परफ़ॉर्मेंस का फिर से आकलन करना

रिसॉर्स के साइज़ और संख्या में हुए बदलाव को देखने के लिए, DevTools नेटवर्क पैनल खोलें और पेज को फिर से लोड करें. नेटवर्क पैनल से पता चलता है कि पेज ने 14 अनुरोध किए थे, लेकिन वह सिर्फ़ 260 केबी की थी. यह एक शानदार सुधार है!

अब पेज पर नीचे की ओर स्क्रोल करें और नेटवर्क पैनल पर नज़र रखें. वीडियो पर पहुंचने के बाद, आपको पेज पर कुछ और अनुरोध दिखेंगे.

ज़रूरी ऑरिजिन से पहले से कनेक्ट करें

आपने गैर-ज़रूरी JavaScript को रोक दिया है और YouTube के अनुरोधों को लेज़ी लोड कर दिया है. इसलिए, अब तीसरे पक्ष के बचे हुए कॉन्टेंट को ऑप्टिमाइज़ करने का समय आ गया है.

किसी लिंक में rel=preconnect एट्रिब्यूट जोड़ने पर, ब्राउज़र को किसी डोमेन से कनेक्ट करने के लिए कहा जाता है. ऐसा, रिसॉर्स के लिए अनुरोध किए जाने से पहले किया जाता है. इस एट्रिब्यूट का सबसे अच्छा इस्तेमाल उन ऑरिजिन पर होता है जो आपके पेज के लिए ज़रूरी संसाधन उपलब्ध कराते हैं.

ज़रूरी ऑरिजिन से प्रीकनेक्ट करें में सुझाए गए पहले चरण में आपने जो लाइटहाउस ऑडिट किया था उसे staticxx.facebook.com और youtube.com पर शुरुआती कनेक्शन बनाकर करीब 400 मि॰से॰ की बचत की जा सकती है:

ज़रूरी ऑरिजिन ऑडिट से पहले से कनेक्ट करें, जिसमें staticxx.facebook.com डोमेन हाइलाइट किया गया हो.

YouTube वीडियो अब लेज़ी लोड है. इसलिए, सिर्फ़ staticxx.facebook.com छोड़ा जा सकता है, जो सोशल मीडिया पर शेयर करने वाले विजेट का सोर्स है. इस डोमेन के साथ शुरुआती कनेक्शन बनाना, दस्तावेज़ के <head> में <link> टैग जोड़ने जितना आसान है:

  <link rel="preconnect" href="https://staticxx.facebook.com">

परफ़ॉर्मेंस का फिर से आकलन करना

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

लाइटहाउस ऑडिट में 1 सेकंड का एफ़सीपी और 99 का परफ़ॉर्मेंस स्कोर दिखाया गया है.