मॉड्यूल पहले से लोड करें

Sérgio Gomes

पब्लिश करने की तारीख: 23 नवंबर, 2024

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

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

<link rel="preload"> इसका इस्तेमाल करके, ब्राउज़र को संसाधनों की ज़रूरत पड़ने से पहले ही, उनका अनुरोध किया जा सकता है.

<head>
  <link rel="preload" as="style" href="critical-styles.css">
  <link rel="preload" as="font" crossorigin type="font/woff2" href="myfont.woff2">
</head>

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

<link rel="preload"> और एचटीटीपी हेडर के बराबर का तरीका, ब्राउज़र को उन ज़रूरी फ़ाइलों के बारे में तुरंत बताने का एक आसान और साफ़ तरीका है जो मौजूदा नेविगेशन के हिस्से के तौर पर ज़रूरी होंगी. जब ब्राउज़र को प्रीलोड का निर्देश मिलता है, तो वह संसाधन को प्राथमिकता के साथ डाउनलोड करना शुरू कर देता है. इससे, जब भी संसाधन की ज़रूरत पड़ती है, तब वह पहले से ही फ़ेच हो जाता है या कुछ हद तक डाउनलोड हो जाता है. हालांकि, यह मॉड्यूल के लिए काम नहीं करता.

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

<script> और <link> टैग के लिए, crossorigin एट्रिब्यूट की मदद से क्रेडेंशियल मोड सेट किया जा सकता है. हालांकि, ऐसा लगता है कि <script type="module"> एलिमेंट में crossorigin एट्रिब्यूट न होने का मतलब है कि क्रेडेंशियल का मोड omit है. यह मोड <link rel="preload"> के लिए मौजूद नहीं है. इसका मतलब है कि आपको <script> और <link>, दोनों में crossorigin एट्रिब्यूट की वैल्यू को बदलकर, किसी दूसरी वैल्यू पर सेट करना होगा. अगर आपको जो कॉन्टेंट प्रीलोड करना है वह दूसरे मॉड्यूल पर निर्भर है, तो ऐसा करना आसान नहीं होगा.

इसके अलावा, कोड को चलाने के लिए, फ़ाइल को फ़ेच करना सिर्फ़ पहला चरण है. सबसे पहले, ब्राउज़र को इसे पार्स और कंपाइल करना होगा. आम तौर पर, ऐसा पहले से भी किया जाना चाहिए, ताकि जब मॉड्यूल की ज़रूरत हो, तब कोड को चलाया जा सके. हालांकि, V8 (Chrome का JavaScript इंजन), मॉड्यूल को अन्य JavaScript के मुकाबले अलग तरीके से पार्स और कंपाइल करता है. <link rel="preload"> से यह पता नहीं चलता कि लोड की जा रही फ़ाइल कोई मॉड्यूल है. इसलिए, ब्राउज़र सिर्फ़ फ़ाइल को लोड करके उसे कैश मेमोरी में सेव कर सकता है. <script type="module"> टैग का इस्तेमाल करके स्क्रिप्ट लोड होने के बाद (या किसी दूसरे मॉड्यूल से लोड होने के बाद), ब्राउज़र कोड को JavaScript मॉड्यूल के तौर पर पार्स और कंपाइल करता है.

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

<head>
  <link rel="modulepreload" href="super-critical-stuff.mjs">
</head>
[...]
<script type="module" src="super-critical-stuff.mjs">

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

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 66.
  • Edge: ≤79.
  • Firefox: 115.
  • Safari: 17.

सोर्स

लेकिन मॉड्यूल की डिपेंडेंसी का क्या होगा?

आपने सही सवाल पूछा! इस लेख में एक चीज़ के बारे में नहीं बताया गया है: रेक्यूर्सन.

<link rel="modulepreload"> स्पेसिफ़िकेशन में, अनुरोध किए गए मॉड्यूल के साथ-साथ, उसके डिपेंडेंसी ट्री को भी लोड करने की सुविधा है. हालांकि, ऐसा करना ज़रूरी नहीं है. ब्राउज़र को ऐसा करने की ज़रूरत नहीं है, लेकिन वे ऐसा कर सकते हैं.

इसलिए, किसी मॉड्यूल और उसके डिपेंडेंसी ट्री को प्रीलोड करने के लिए, क्रॉस-ब्राउज़र का सबसे अच्छा तरीका क्या होगा, क्योंकि ऐप्लिकेशन को चलाने के लिए आपको पूरे डिपेंडेंसी ट्री की ज़रूरत होगी?

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

<head>
  <!-- dog.js imports dog-head.js, which in turn imports
       dog-head-mouth.js, which imports dog-head-mouth-tongue.js. -->
  <link rel="modulepreload" href="dog-head-mouth-tongue.mjs">
  <link rel="modulepreload" href="dog-head-mouth.mjs">
  <link rel="modulepreload" href="dog-head.mjs">
  <link rel="modulepreload" href="dog.mjs">
</head>

क्या मॉड्यूल को पहले से लोड करने से परफ़ॉर्मेंस बेहतर होती है?

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

हालांकि, मॉड्यूल की परफ़ॉर्मेंस पर अब भी काम किया जा रहा है. इसलिए, पक्का करें कि आपने डेवलपर टूल की मदद से, अपने ऐप्लिकेशन में हो रही प्रोसेस की बारीकी से जांच की हो. साथ ही, इस दौरान अपने ऐप्लिकेशन को कई हिस्सों में बांटने पर विचार करें. हालांकि, Chrome में मॉड्यूल से जुड़ा काफ़ी काम चल रहा है. इसलिए, हम जल्द ही बंडलर को आराम देने वाले हैं!