प्रीफ़ेच करने के दो तरीके: <link> टैग और एचटीटीपी हेडर

Demián Renzulli
Demián Renzulli

इस कोडलैब में, प्रीफ़ेचिंग को दो तरीकों से लागू किया जाएगा: <link rel="prefetch"> और एचटीटीपी Link हेडर की मदद से.

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

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

सबसे पहले, परफ़ॉर्मेंस की बेसलाइन तय करें:

  1. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  2. नेटवर्क टैब पर क्लिक करें.

  3. कनेक्शन की स्पीड कम करने के लिए, थ्रॉटलिंग ड्रॉप-डाउन सूची में जाकर, फ़ास्ट 3G चुनें.

  4. प्रॉडक्ट पेज लोड करने के लिए, सैंपल ऐप्लिकेशन में अभी खरीदें पर क्लिक करें.

product-details.html पेज को लोड होने में करीब 600 मि॰से॰ लगते हैं:

नेटवर्क पैनल में, product-details.html के लोड होने का समय दिखाया गया है

नेविगेशन को बेहतर बनाने के लिए, लैंडिंग पेज में prefetch टैग डालें, ताकि product-details.html पेज को पहले से फ़ेच किया जा सके:

  • views/index.html फ़ाइल के हेड में यह <link> एलिमेंट जोड़ें:
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

as एट्रिब्यूट का इस्तेमाल करना ज़रूरी नहीं है, लेकिन इसका इस्तेमाल करने का सुझाव दिया जाता है. इससे ब्राउज़र को सही हेडर सेट करने में मदद मिलती है. साथ ही, यह तय करने में मदद मिलती है कि संसाधन पहले से ही कैश मेमोरी में है या नहीं. इस एट्रिब्यूट की वैल्यू के उदाहरण: document, script, style, font, image, और अन्य.

प्रीफ़ेचिंग की सुविधा काम कर रही है या नहीं, इसकी पुष्टि करने के लिए:

  1. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  2. नेटवर्क टैब पर क्लिक करें.

  3. कनेक्शन की स्पीड कम करने के लिए, थ्रॉटलिंग ड्रॉप-डाउन सूची में जाकर, फ़ास्ट 3G चुनें.

  4. 'कैश मेमोरी की सुविधा बंद करें' चेकबॉक्स से सही का निशान हटाएं.

  5. ऐप्लिकेशन को फिर से लोड करें.

अब लैंडिंग पेज लोड होने पर, product-details.html पेज भी लोड हो जाता है. हालांकि, इसे सबसे कम प्राथमिकता दी जाती है:

नेटवर्क पैनल में, product-details.html को पहले से फ़ेच किया गया दिखाया गया है.

पेज को पांच मिनट के लिए एचटीटीपी कैश मेमोरी में रखा जाता है. इसके बाद, दस्तावेज़ पर सामान्य Cache-Control नियम लागू होते हैं. इस मामले में, product-details.html में cache-control हेडर है, जिसकी वैल्यू public, max-age=0 है. इसका मतलब है कि पेज को कुल पांच मिनट तक सेव रखा जाता है.

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

  1. ऐप्लिकेशन को फिर से लोड करें.
  2. प्रॉडक्ट पेज लोड करने के लिए, सैंपल ऐप्लिकेशन में अभी खरीदें पर क्लिक करें.

नेटवर्क पैनल देखें. नेटवर्क ट्रेस की शुरुआती स्थिति की तुलना में, यहां दो अंतर हैं:

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

यह पिछले वर्शन की तुलना में करीब 98% कम है. पिछले वर्शन में, इसमें करीब 600 मि॰से॰ लगते थे.

नेटवर्क पैनल में, प्रीफ़ेच कैश मेमोरी से वापस लाई गई product-details.html फ़ाइल दिखाई गई है.

अतिरिक्त क्रेडिट: prefetch को प्रोग्रेसिव एन्हांसमेंट के तौर पर इस्तेमाल करें

प्रीफ़ेच करने की सुविधा को, तेज़ इंटरनेट कनेक्शन पर ब्राउज़ करने वाले लोगों के लिए, प्रोग्रेसिव एन्हांसमेंट के तौर पर सबसे अच्छी तरह से लागू किया जाता है. Network Information API का इस्तेमाल करके, नेटवर्क की स्थितियों की जांच की जा सकती है. इसके आधार पर, प्रीफ़ेच टैग को डाइनैमिक तरीके से इंजेक्ट किया जा सकता है. इस तरह, डेटा की खपत को कम किया जा सकता है. साथ ही, धीमे या महंगे डेटा प्लान का इस्तेमाल करने वाले लोगों के लिए, लागत को बचाया जा सकता है.

अडैप्टिव प्रीफ़ेचिंग लागू करने के लिए, सबसे पहले views/index.html से <link rel="prefetch"> टैग हटाएं:

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

इसके बाद, public/script.js में यह कोड जोड़ें, ताकि एक फ़ंक्शन का एलान किया जा सके. यह फ़ंक्शन, उपयोगकर्ता के तेज़ इंटरनेट कनेक्शन पर होने पर prefetch टैग को डाइनैमिक तरीके से इंजेक्ट करता है:

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

यह फ़ंक्शन इस तरह काम करता है:

  • यह कुकी, Network Information API की effectiveType प्रॉपर्टी की जांच करती है. इससे यह पता चलता है कि उपयोगकर्ता 4G (या इससे तेज़) कनेक्शन पर है या नहीं.
  • अगर यह शर्त पूरी हो जाती है, तो यह <link> टैग जनरेट करता है. इसमें prefetch को हिंट के टाइप के तौर पर सेट किया जाता है. साथ ही, href एट्रिब्यूट में उस यूआरएल को पास किया जाता है जिसे प्रीफ़ेच किया जाएगा. इसके अलावा, as एट्रिब्यूट में यह बताया जाता है कि संसाधन एक एचटीएमएल document है.
  • आखिर में, यह पेज के head में स्क्रिप्ट को डाइनैमिक तरीके से इंजेक्ट करता है.

इसके बाद, </body> टैग बंद होने से ठीक पहले, views/index.html में script.js जोड़ें:

<body>
      ...
      <script src="/script.js"></script>
</body>

पेज के आखिर में script.js का अनुरोध करने से यह पक्का होता है कि पेज को पार्स और लोड करने के बाद, इसे लोड और एक्ज़ीक्यूट किया जाएगा.

यह पक्का करने के लिए कि प्रीफ़ेचिंग, मौजूदा पेज के ज़रूरी संसाधनों में रुकावट न डाले, window.load इवेंट पर injectLinkPrefetchIn4g() को कॉल करने के लिए, यह कोड स्निपेट जोड़ें:

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

अब लैंडिंग पेज, product-details.html को सिर्फ़ तेज़ कनेक्शन पर प्रीफ़ेच करता है. इसकी पुष्टि करने के लिए:

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

आपको नेटवर्क पैनल में product-details.html दिखेगा:

नेटवर्क पैनल में, product-details.html को पहले से फ़ेच किया गया दिखाया गया है.

यह पुष्टि करने के लिए कि धीमी इंटरनेट स्पीड पर प्रॉडक्ट पेज को प्रीफ़ेच नहीं किया गया है:

  1. थ्रॉटलिंग की ड्रॉप-डाउन सूची में, Slow 3G चुनें.
  2. ऐप्लिकेशन को फिर से लोड करें.

नेटवर्क पैनल में, सिर्फ़ लैंडिंग पेज के रिसॉर्स शामिल होने चाहिए. इनमें product-details.html शामिल नहीं होने चाहिए:

नेटवर्क पैनल में दिखाया गया है कि product-details.html को पहले से फ़ेच नहीं किया जा रहा है.

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

लैंडिंग पेज के लिए सर्वर रिस्पॉन्स में, style-product.css के लिए एचटीटीपी Link हेडर जोड़ें:

  1. server.js फ़ाइल खोलें और रूट यूआरएल / के लिए get() हैंडलर ढूंढें.
  2. हैंडलर की शुरुआत में यह लाइन जोड़ें:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  2. नेटवर्क टैब पर क्लिक करें.
  3. ऐप्लिकेशन को फिर से लोड करें.

लैंडिंग पेज लोड होने के बाद, style-product.css को सबसे कम प्राथमिकता पर प्रीफ़ेच किया जाता है:

नेटवर्क पैनल में style-product.css को प्रीफ़ेच किया गया है.

प्रॉडक्ट पेज पर जाने के लिए, अभी खरीदें पर क्लिक करें. नेटवर्क पैनल देखें:

नेटवर्क पैनल में, प्रीफ़ेच कैश मेमोरी से स्टाइल-product.css को वापस लाया गया है.

style-product.css फ़ाइल को "प्रीफ़ेच कैश मेमोरी" से वापस लाया गया है. इसे लोड होने में सिर्फ़ 12 मि॰से॰ लगे.