कोडलैब (कोड बनाना सीखना): कॉन्टेंट लोड होने की स्पीड बढ़ाने के लिए, अहम एसेट को पहले से लोड करना

इस कोडलैब में, कुछ रिसॉर्स को प्रीलोड और प्रीफ़ेच करके, नीचे दिए गए वेब पेज की परफ़ॉर्मेंस को बेहतर बनाया गया है:

ऐप्लिकेशन का स्क्रीनशॉट

मापें

कोई भी ऑप्टिमाइज़ेशन जोड़ने से पहले, यह मेज़र करें कि वेबसाइट की परफ़ॉर्मेंस कैसी है.

  • साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन दबाएं.

अपने Glitch के लाइव वर्शन पर, लाइटहाउस परफ़ॉर्मेंस ऑडिट (Lighthouse > विकल्प > परफ़ॉर्मेंस) चलाएं. साथ ही, Lighthouse की मदद से परफ़ॉर्मेंस से जुड़े अवसरों को ढूंढें लेख भी पढ़ें.

Lighthouse, देर से फ़ेच किए गए रिसॉर्स के लिए, ऑडिट में फ़ेल होने का यह मैसेज दिखाता है:

Lighthouse: मुख्य अनुरोधों को पहले से लोड करने की सुविधा का ऑडिट
  • DevTools खोलने के लिए, `Control+Shift+J` दबाएं. Mac पर, `Command+Option+J` दबाएं.
  • नेटवर्क टैब पर क्लिक करें.
देर से खोजे गए रिसॉर्स वाला नेटवर्क पैनल

main.css फ़ाइल को एचटीएमएल दस्तावेज़ में मौजूद लिंक एलिमेंट (<link>) से फ़ेच नहीं किया जाता. हालांकि, fetch-css.js नाम की एक अलग JavaScript फ़ाइल, window.onLoad इवेंट के बाद लिंक एलिमेंट को डीओएम से जोड़ती है. इसका मतलब है कि ब्राउज़र, JS फ़ाइल को पार्स और एक्ज़ीक्यूट करने के बाद ही फ़ाइल को फ़ेच करता है. इसी तरह, main.css में बताए गए वेब फ़ॉन्ट (K2D.woff2) को सिर्फ़ तब फ़ेच किया जाता है, जब सीएसएस फ़ाइल डाउनलोड हो जाती है.

अहम अनुरोध चेन, उन संसाधनों के क्रम को दिखाती है जिन्हें ब्राउज़र प्राथमिकता देता है और फ़ेच करता है. फ़िलहाल, इस वेब पेज का दिखने का तरीका कुछ ऐसा है:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

सीएसएस फ़ाइल, अनुरोध चेन के तीसरे लेवल पर है. इसलिए, Lighthouse ने इसे देर से खोजे गए रिसॉर्स के तौर पर पहचाना है.

ज़रूरी रिसॉर्स प्रीलोड करना

main.css फ़ाइल एक अहम एसेट है, जिसकी ज़रूरत पेज लोड होने के तुरंत बाद पड़ती है. इस रिसॉर्स जैसी अहम फ़ाइलों के लिए, लिंक प्रीलोड टैग का इस्तेमाल करें. इससे ब्राउज़र को फ़ाइल को जल्दी डाउनलोड करने के लिए कहा जा सकता है. इसके लिए, दस्तावेज़ के हेड में लिंक एलिमेंट जोड़ें.

इस ऐप्लिकेशन के लिए, प्रीलोड टैग जोड़ें:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

as एट्रिब्यूट का इस्तेमाल, यह पता लगाने के लिए किया जाता है कि किस तरह का संसाधन फ़ेच किया जा रहा है. साथ ही, as="style" का इस्तेमाल स्टाइलशीट फ़ाइलों को पहले से लोड करने के लिए किया जाता है.

ऐप्लिकेशन को फिर से लोड करें और DevTools में नेटवर्क पैनल देखें.

पहले से लोड किए गए रिसॉर्स वाला नेटवर्क पैनल

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

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

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

ऐप्लिकेशन को फिर से लोड करें और नेटवर्क पैनल देखें. details.css को वापस पाने का अनुरोध किया जाता है, भले ही वेब पेज उसका इस्तेमाल न कर रहा हो.

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

जब पेज पर पहले से लोड किए गए किसी संसाधन का इस्तेमाल, लोड होने के कुछ सेकंड के अंदर नहीं किया जाता, तो Chrome कंसोल पैनल में चेतावनी दिखाता है.

कंसोल में प्रीलोड करने से जुड़ी चेतावनी

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

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

as एट्रिब्यूट के लिए इस्तेमाल की जा सकने वाली सही वैल्यू के साथ-साथ, फ़ेच किए जा सकने वाले सभी तरह के संसाधनों की सूची के लिए, प्रीलोड करने के बारे में MDN का लेख पढ़ें.

आने वाले समय में इस्तेमाल होने वाले संसाधनों को पहले से लोड करना

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

इस वेबसाइट में, इमेज पर क्लिक करने से आपको एक अलग details/ रास्ते पर ले जाया जाता है.

रास्ते की जानकारी

details.css नाम की एक अलग सीएसएस फ़ाइल में, इस आसान पेज के लिए ज़रूरी सभी स्टाइल मौजूद हैं. इस संसाधन को पहले से लोड करने के लिए, index.html में लिंक एलिमेंट जोड़ें.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

यह समझने के लिए कि यह फ़ाइल के लिए अनुरोध कैसे ट्रिगर करता है, DevTools में नेटवर्क पैनल खोलें और कैश मेमोरी बंद करें विकल्प से सही का निशान हटाएं.

Chrome DevTools में कैश मेमोरी में सेव करने की सुविधा बंद करना

ऐप्लिकेशन को फिर से लोड करें और देखें कि अन्य सभी फ़ाइलें फ़ेच होने के बाद, details.css के लिए बहुत कम प्राथमिकता वाला अनुरोध कैसे किया जाता है.

पहले से फ़ेच किए गए रिसॉर्स वाला नेटवर्क पैनल

DevTools खोलकर, details पेज पर जाने के लिए वेबसाइट पर मौजूद इमेज पर क्लिक करें. details.css को फ़ेच करने के लिए, details.html में लिंक एलिमेंट का इस्तेमाल किया जाता है. इसलिए, उम्मीद के मुताबिक संसाधन के लिए अनुरोध किया जाता है.

ज़्यादा जानकारी वाले पेज के लिए नेटवर्क से जुड़े अनुरोध

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

डिस्क कैश मेमोरी से फ़ेच की गई जानकारी का अनुरोध

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

webpack की मदद से, पहले से लोड करना और प्रीफ़ेच करना

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

कोड को अलग-अलग हिस्सों में बांटने की सुविधा दिखाने वाला Magic Sorter ऐप्लिकेशन

इस ऐप्लिकेशन के लिए Glitch को यहां ऐक्सेस किया जा सकता है.

src/index.js, में मौजूद कोड का यह ब्लॉक, बटन पर क्लिक करने पर, डाइनैमिक तौर पर तरीका इंपोर्ट करने के लिए ज़िम्मेदार है.

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

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

किसी खास चंक को पहले से लोड करने के लिए, डाइनैमिक इंपोर्ट में webpackPrefetch टिप्पणी पैरामीटर का इस्तेमाल करें. इस ऐप्लिकेशन में यह सुविधा कैसी दिखेगी, यहां देखें.

form.addEventListener("submit", e => {
  e.preventDefault()
  import(/* webpackPrefetch: true */ 'lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

ऐप्लिकेशन फिर से लोड होने के बाद, वेबपैक दस्तावेज़ के हेड में, संसाधन के लिए प्रीफ़ेच टैग इंजेक्ट करता है. इसे DevTools में एलिमेंट पैनल में देखा जा सकता है.

प्रीफ़ेच टैग वाला एलिमेंट पैनल

नेटवर्क पैनल में अनुरोधों को देखकर यह भी पता चलता है कि अन्य सभी संसाधनों के अनुरोध किए जाने के बाद, इस चंक को कम प्राथमिकता के साथ फ़ेच किया जाता है.

पहले से फ़ेच किए गए अनुरोध वाला नेटवर्क पैनल

हालांकि, इस इस्तेमाल के उदाहरण के लिए प्रीफ़ेच का इस्तेमाल करना ज़्यादा सही है, लेकिन webpack डाइनैमिक तौर पर इंपोर्ट किए गए चंक को प्रीलोड करने की सुविधा भी देता है.

import(/* webpackPreload: true */ 'module')

नतीजा

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

खास जानकारी के लिए:

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

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

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