ब्राउज़र प्रीलोड स्कैनर से मुकाबला न करें

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

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

ब्राउज़र प्रीलोड स्कैनर को समझने के लिए एक इंटरनल ब्राउज़र ऑप्टिमाइज़ेशन है. इस पोस्ट में बताया जाएगा कि प्रीलोड स्कैनर कैसे काम करता है—और सबसे अहम बात यह है कि इस प्रोसेस में आने से कैसे बचें.

प्रीलोड स्कैनर क्या है?

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

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

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

web.dev होम पेज, बिना स्टाइल (बाएं) और स्टाइल स्थिति (दाएं) में है.
इमेज. 2: FOUC का एक सिम्युलेटेड उदाहरण. बाईं ओर बिना स्टाइल के web.dev का मुख्य पेज है. दाईं ओर, वही पेज दिख रहा है जिस पर स्टाइल लागू की गई हैं. अगर स्टाइलशीट के डाउनलोड और प्रोसेस होने के दौरान ब्राउज़र रेंडरिंग को ब्लॉक नहीं करता, तो बिना स्टाइल वाली स्थिति फ़्लैश हो सकती है.

जब ब्राउज़र को defer या async एट्रिब्यूट के बिना <script> एलिमेंट मिलते हैं, तो ब्राउज़र उस पेज को पार्स और रेंडर करने से भी रोकता है.

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

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

प्राइमरी एचटीएमएल पार्सर (बाईं ओर) और प्रीलोड स्कैनर (दाईं ओर) का डायग्राम. प्रीलोड स्कैनर, सेकंडरी एचटीएमएल पार्सर होता है.
इमेज. 3: डायग्राम में दिखाया गया है कि पहले से लोड करने वाला स्कैनर, प्राइमरी एचटीएमएल पार्सर के साथ, अनुमान के हिसाब से ऐसेट लोड करने के लिए कैसे काम करता है. यहां प्राइमरी एचटीएमएल पार्सर को ब्लॉक कर दिया जाता है, क्योंकि वह सीएसएस को लोड और प्रोसेस करता है. ऐसा करने से वह <body> एलिमेंट में इमेज मार्कअप को प्रोसेस करना शुरू कर देता है. हालांकि, पहले से लोड किया गया स्कैनर, रॉ मार्कअप में आगे की ओर देखकर, उस इमेज रिसॉर्स को ढूंढ सकता है और प्राइमरी एचटीएमएल पार्सर के अनब्लॉक होने से पहले उसे लोड कर सकता है.

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

यह कैसे बताएं कि प्रीलोड स्कैनर कब काम कर रहा है

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

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

WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट में, स्टाइलशीट पर लगाए गए दो सेकंड की आर्टिफ़िशियल देरी को दिखाया गया है.
इमेज. 4: मोबाइल डिवाइस में, सिम्युलेटेड 3G कनेक्शन के ज़रिए Chrome पर चलता है वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट. भले ही प्रॉक्सी के माध्यम से स्टाइलशीट के लोड होने से पहले दो सेकंड की देरी हो जाए, लेकिन प्रीलोड स्कैनर द्वारा बाद में मार्कअप पेलोड में बाद में मौजूद चित्र को खोजा जा सकता है.

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

खिलौने के इस उदाहरण को देखते हुए, आइए अब असल दुनिया के कुछ पैटर्न पर नज़र डालते हैं. इनमें, प्रीलोड स्कैनर को हराया जा सकता है और इन पैटर्न को ठीक करने के लिए क्या किया जा सकता है.

इंजेक्ट की गई async स्क्रिप्ट

मान लें कि आपके <head> में एचटीएमएल है, जिसमें कुछ इनलाइन JavaScript शामिल हैं, जैसे कि:

<script>
  const scriptEl = document.createElement('script');
  scriptEl.src = '/yall.min.js';

  document.head.appendChild(scriptEl);
</script>

इंजेक्ट की गई स्क्रिप्ट डिफ़ॉल्ट रूप से async होती हैं. इसलिए, जब यह स्क्रिप्ट इंजेक्ट की जाती है, तो यह इस तरह काम करती है जैसे उस पर async एट्रिब्यूट लागू किया गया हो. इसका मतलब है कि यह जल्द से जल्द काम करेगा और रेंडरिंग को ब्लॉक नहीं करेगा. यह सही है, है न? इसके बावजूद, अगर आपको लगता है कि यह इनलाइन <script> किसी <link> एलिमेंट के बाद आता है जो किसी बाहरी सीएसएस फ़ाइल को लोड करता है, तो आपको खराब नतीजा मिलेगा:

यह WebPageTest चार्ट, स्क्रिप्ट शामिल किए जाने पर प्रीलोड स्कैन को रोका गया है.
इमेज. 5: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. इस पेज पर एक स्टाइलशीट और इंजेक्ट की गई एक async स्क्रिप्ट होती है. रेंडर करने से रोकने के दौरान, प्रीलोड स्कैनर स्क्रिप्ट को नहीं खोज पाता. ऐसा इसलिए होता है, क्योंकि इसे क्लाइंट में डाला जाता है.

आइए, इस बारे में ज़्यादा जानें:

  1. 0 सेकंड पर, मुख्य दस्तावेज़ का अनुरोध किया जाता है.
  2. 1.4 सेकंड पर, नेविगेशन अनुरोध का पहला बाइट आता है.
  3. 2.0 सेकंड पर, सीएसएस और इमेज का अनुरोध किया जाता है.
  4. पार्सर को स्टाइलशीट और इनलाइन JavaScript को लोड करने से रोका जाता है, जो async स्क्रिप्ट को इंजेक्ट करते हैं और उस स्टाइलशीट के बाद में 2.6 सेकंड पर आते हैं. इस वजह से, स्क्रिप्ट जो सुविधा देती है वह जल्द से जल्द उपलब्ध नहीं होती.

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

इसलिए, अगर आप स्क्रिप्ट को डीओएम में इंजेक्ट करने के बजाय, async एट्रिब्यूट के साथ किसी सामान्य <script> टैग का इस्तेमाल करते हैं, तो क्या होगा?

<script src="/yall.min.js" async></script>

यह रहा नतीजा:

यह WebPageTest नेटवर्क वॉटरफ़ॉल दिखाता है कि एचटीएमएल स्क्रिप्ट एलिमेंट का इस्तेमाल करके लोड की गई एसिंक्रोनस स्क्रिप्ट, ब्राउज़र के प्रीलोड स्कैनर से कैसे खोजी जा सकती है. भले ही, स्टाइलशीट को डाउनलोड और प्रोसेस करते समय ब्राउज़र का प्राइमरी एचटीएमएल पार्सर ब्लॉक हो जाता है.
इमेज. 6: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. इस पेज पर एक स्टाइलशीट और एक async <script> एलिमेंट होता है. रेंडर करने की प्रोसेस रोकने के दौरान, प्रीलोड स्कैनर स्क्रिप्ट को ढूंढता है और उसे सीएसएस के साथ लोड करता है.

ऐसा हो सकता है कि आप यह सुझाव देना चाहें कि rel=preload का इस्तेमाल करके इन समस्याओं को हल किया जा सकता है. यह निश्चित तौर पर कारगर होगा, लेकिन इसके कुछ खराब असर हो सकते हैं. आखिरकार, DOM में <script> एलिमेंट इंजेक्ट नहीं करके, उस समस्या को ठीक करने के लिए rel=preload का इस्तेमाल क्यों करें?

WebPageTest वॉटरफ़ॉल में यह दिखाया गया है कि aसिंक इंजेक्ट की गई स्क्रिप्ट को खोजने के लिए, rel=preload संसाधन संकेत का इस्तेमाल कैसे किया जाता है. यह इस तरह से दिखाया गया है जिससे अनचाहे खराब असर पड़ सकते हैं.
इमेज. 7: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. इस पेज पर एक स्टाइलशीट और इंजेक्ट की गई async स्क्रिप्ट होती है, लेकिन async स्क्रिप्ट पहले से लोड की जाती है, ताकि यह पक्का किया जा सके कि इसे जल्दी खोजा जा सके.

"सुधार" पहले से लोड किया जा रहा है यहां समस्या आ रही है, लेकिन इससे एक नई समस्या आ गई है: पहले दो डेमो में async स्क्रिप्ट—<head> में लोड होने के बावजूद—ये "कम" पर लोड होती हैं प्राथमिकता पर सेट कर सकते हैं, जबकि स्टाइलशीट "सबसे ज़्यादा" पर लोड होती है प्राथमिकता तय करें. पिछले डेमो में जहां async स्क्रिप्ट पहले से लोड की गई है, उसमें स्टाइलशीट अब भी "सबसे ज़्यादा" पर लोड होती है प्राथमिकता पर लागू किया गया है, लेकिन स्क्रिप्ट की प्राथमिकता से आगे बढ़कर "उच्च" कर दिया गया है.

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

यहां दिया गया जवाब आसान है: अगर स्टार्टअप के दौरान स्क्रिप्ट की ज़रूरत हो, तो पहले से लोड किए गए स्कैनर को डीओएम में इंजेक्ट करने से न रोकें. ज़रूरत के हिसाब से, <script> एलिमेंट के प्लेसमेंट के साथ-साथ defer और async जैसे एट्रिब्यूट के साथ प्रयोग करें.

JavaScript की मदद से लेज़ी लोडिंग

लेज़ी लोडिंग, डेटा को सुरक्षित रखने का एक बेहतरीन तरीका है. इसका इस्तेमाल अक्सर इमेज पर किया जाता है. हालांकि, कभी-कभी "पेज के ऊपरी हिस्से" पर मौजूद इमेज पर लेज़ी लोडिंग का तरीका गलत तरीके से लागू हो जाता है.

इसकी मदद से, उन समस्याओं के बारे में पता चलता है जिन्हें पहले से लोड करने वाले स्कैनर की जांच की जाती है. साथ ही, इससे किसी इमेज का रेफ़रंस खोजने, उसे डाउनलोड करने, डिकोड करने, और उसे प्रज़ेंट करने में लगने वाला समय भी बेवजह देरी हो सकता है. चलिए, इस इमेज मार्कअप का उदाहरण लेते हैं:

<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

JavaScript से चलने वाले लेज़ी लोडर में, data- प्रीफ़िक्स का इस्तेमाल एक आम पैटर्न है. जब इमेज को व्यूपोर्ट में स्क्रोल किया जाता है, तो लेज़ी लोडर data- प्रीफ़िक्स को हटा देता है. इसका मतलब है कि पिछले उदाहरण में, data-src src बन जाता है. यह अपडेट, ब्राउज़र को संसाधन फ़ेच करने के लिए कहता है.

इस पैटर्न में तब तक कोई समस्या नहीं आती, जब तक इसे स्टार्टअप के दौरान व्यूपोर्ट में मौजूद इमेज पर लागू नहीं किया जाता. प्रीलोड स्कैनर, data-src एट्रिब्यूट को उसी तरह नहीं पढ़ता जिस तरह वह src (या srcset) एट्रिब्यूट को पढ़ता है. इसलिए, इमेज का रेफ़रंस पहले नहीं मिलता. इससे भी खराब बात यह है कि लेज़ी लोडर JavaScript डाउनलोड, कंपाइल, और एक्ज़ीक्यूट करने के बाद इमेज लोड नहीं होती है.

WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट में यह दिखाया गया है कि स्टार्टअप के दौरान व्यूपोर्ट में लेज़ी से लोड की गई इमेज में देरी कैसे हो सकती है. इसकी वजह यह है कि ब्राउज़र पहले से लोड किए गए स्कैनर को इमेज रिसॉर्स नहीं मिलता. यह सिर्फ़ तब लोड होता है, जब लेज़ी लोडिंग के लिए JavaScript ज़रूरी होता है. इमेज काफ़ी बाद में मिली है.
इमेज. 8: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. इमेज रिसॉर्स को ज़रूरत से ज़्यादा लेज़ी-लोड किया गया है. भले ही, यह स्टार्टअप के दौरान व्यूपोर्ट में दिख रहा हो. इससे, प्रीलोड स्कैनर काम नहीं करता और इसकी वजह से बेवजह की देरी होती है.

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

इसका समाधान है कि इमेज मार्कअप बदलें:

<img src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

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

WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जिसमें स्टार्टअप के दौरान व्यूपोर्ट में इमेज लोड होने की स्थिति को दिखाया गया है. इमेज को लेज़ी तरीके से लोड नहीं किया गया है. इसका मतलब है कि यह लोड होने वाली स्क्रिप्ट पर निर्भर नहीं है. इसका मतलब है कि इमेज को पहले से लोड करने वाला स्कैनर इसे जल्दी ढूंढ सकता है.
इमेज. 9: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. सीएसएस और JavaScript के लोड होने से पहले, प्रीलोड स्कैनर इमेज रिसॉर्स को ढूंढ लेता है. इससे ब्राउज़र को इमेज लोड होने में मदद मिलती है.

इस आसान उदाहरण से, धीमे कनेक्शन पर एलसीपी में 100 मिलीसेकंड का सुधार दिखता है. ऐसा लग सकता है कि यह बहुत बड़ा सुधार नहीं लग सकता, लेकिन यह तब होता है, जब आप इस बात पर ध्यान देते हैं कि मार्कअप को तुरंत ठीक किया जा सकता है और ज़्यादातर वेब पेज, उदाहरणों के इस सेट से ज़्यादा जटिल होते हैं. इसका मतलब है कि एलसीपी उम्मीदवारों को कई दूसरे संसाधनों के साथ बैंडविथ के लिए संघर्ष करना पड़ सकता है. इसलिए, इस तरह के ऑप्टिमाइज़ेशन का महत्व और भी बढ़ जाता है.

सीएसएस के बैकग्राउंड की इमेज

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

एचटीएमएल की तरह, ब्राउज़र भी सीएसएस को उसके अपने ऑब्जेक्ट मॉडल में प्रोसेस करते हैं. इसे CSSOM कहा जाता है. अगर सीएसएसओएम बनाते समय बाहरी रिसॉर्स मिलते हैं, तो उन रिसॉर्स के लिए अनुरोध, खोजने के समय किया जाता है, न कि प्रीलोड स्कैनर से.

मान लें कि आपके पेज का एलसीपी कैंडिडेट, सीएसएस background-image प्रॉपर्टी वाला कोई एलिमेंट है. संसाधन लोड होने पर, ये काम होते हैं:

WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जिसमें एक ऐसा पेज दिखाया गया है जिसमें बैकग्राउंड-इमेज प्रॉपर्टी का इस्तेमाल करके, सीएसएस से एलसीपी उम्मीदवार लोड किया गया है. एलसीपी उम्मीदवार की इमेज एक ऐसे संसाधन टाइप में है जिसकी जांच ब्राउज़र प्रीलोड स्कैनर नहीं कर सकता. इसलिए, संसाधन तब तक लोड नहीं होता, जब तक कि सीएसएस डाउनलोड और प्रोसेस नहीं हो जाती. इससे एलसीपी कैंडिडेट को पेंट करने में देरी होती है.
इमेज. 10: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. पेज का एलसीपी कैंडिडेट, सीएसएस background-image प्रॉपर्टी (तीसरी लाइन) वाला एलिमेंट है. अनुरोध की जाने वाली इमेज तब तक फ़ेच नहीं होगी, जब तक सीएसएस पार्सर को वह इमेज नहीं मिल जाती.

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

<!-- Make sure this is in the <head> below any
     stylesheets, so as not to block them from loading -->
<link rel="preload" as="image" href="lcp-image.jpg">

यह rel=preload संकेत छोटा है, लेकिन इससे इमेज को पहले खोजने में ब्राउज़र को मदद मिलती है, क्योंकि यह नहीं दिखाया जाता:

WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जिसमें सीएसएस बैकग्राउंड इमेज (जो एलसीपी कैंडिडेट है) को दिखाया गया है. यह rel=preload संकेत का इस्तेमाल करने की वजह से बहुत जल्दी लोड हो रहा है. एलसीपी समय करीब 250 मिलीसेकंड तक बढ़ जाता है.
इमेज. 11: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. पेज का एलसीपी कैंडिडेट, सीएसएस background-image प्रॉपर्टी (तीसरी लाइन) वाला एलिमेंट है. rel=preload संकेत से, ब्राउज़र को बिना संकेत के इमेज को 250 मिलीसेकंड के आस-पास खोजने में मदद मिलती है.

rel=preload से मिलने वाले संकेत से एलसीपी उम्मीदवार के बारे में जल्दी पता चल जाता है. इससे एलसीपी में कम समय लगता है. इस संकेत से इस समस्या को ठीक करने में मदद मिलती है. हालांकि, बेहतर तरीका यह है कि आप इस बात का आकलन करें कि आपके इमेज के एलसीपी उम्मीदवार को सीएसएस से लोड किया गया है या नहीं. <img> टैग की मदद से, आपके पास ऐसी इमेज को लोड करने के लिए ज़्यादा कंट्रोल होगा जो व्यूपोर्ट के हिसाब से सही हो. साथ ही, प्रीलोड स्कैनर को वह इमेज खोजने की अनुमति भी मिलती है जो व्यूपोर्ट के हिसाब से सही है.

बहुत ज़्यादा रिसॉर्स इनलाइन करना

इनलाइनिंग एक ऐसी प्रोसेस है जिसमें रिसॉर्स को एचटीएमएल में रखा जाता है. base64 एन्कोडिंग का इस्तेमाल करके, <style> एलिमेंट में स्टाइलशीट, <script> एलिमेंट में स्क्रिप्ट, और वर्चुअल तौर पर किसी भी अन्य संसाधन को इनलाइन किया जा सकता है.

संसाधनों को डाउनलोड करने के मुकाबले, उन्हें इनलाइन करना काफ़ी तेज़ हो सकता है. ऐसा इसलिए, क्योंकि संसाधन के लिए अलग से कोई अनुरोध नहीं किया गया होता है. यह दस्तावेज़ में सही होता है और तुरंत लोड हो जाता है. हालांकि, इसमें कुछ समस्याएं हैं:

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

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

बाहरी सीएसएस फ़ाइल के साथ इस पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट. इसमें चार फ़ॉन्ट के बारे में बताया गया है. तय समय के दौरान, प्रीलोड स्कैनर को एलसीपी उम्मीदवार की इमेज मिल जाती है.
इमेज 12: किसी वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो सिम्युलेट किए गए 3G कनेक्शन पर मोबाइल डिवाइस पर Chrome पर चलाया गया है. पेज का एलसीपी कैंडिडेट, <img> एलिमेंट से लोड की गई इमेज है. हालांकि, इसे प्रीलोड स्कैनर से खोजा जाता है, क्योंकि पेज के लिए ज़रूरी सीएसएस और फ़ॉन्ट अलग-अलग रिसॉर्स में लोड होते हैं. इससे प्रीलोड स्कैनर को अपना काम करने में देरी नहीं होती.

अब क्या होगा अगर सीएसएस और सभी फ़ॉन्ट बेस64 रिसॉर्स के तौर पर इनलाइन हैं?

WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जिसमें बाहरी सीएसएस फ़ाइल के साथ पेज को दिखाया गया है. इसमें चार फ़ॉन्ट का रेफ़रंस दिया गया है. एलसीपी इमेज खोजने में, प्रीलोड स्कैनर को बहुत देरी हो रही है .
इमेज. 13: वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो Chrome में एक मोबाइल डिवाइस पर सिम्युलेट किए गए 3G कनेक्शन के ज़रिए चलता है. पेज का एलसीपी कैंडिडेट, एक ऐसी इमेज है जिसे <img> एलिमेंट से लोड किया गया है. हालांकि, `` में सीएसएस की इनलाइनिंग और इसके चार फ़ॉन्ट रिसॉर्स होने से, प्रीलोड स्कैनर को इमेज खोजने में तब तक देरी होती है, जब तक उन रिसॉर्स को पूरी तरह डाउनलोड नहीं किया जाता.

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

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

क्या पहले से लोड करने से यहां चीज़ें बेहतर हो सकती हैं? बेशक। एलसीपी इमेज को पहले से लोड करके और एलसीपी के समय को भी कम किया जा सकता है. हालांकि, इनलाइन रिसॉर्स की मदद से, उस एचटीएमएल को बड़ा किया जा सकता है जिसे कैश मेमोरी में सेव नहीं किया जा सकता. हालांकि, इससे परफ़ॉर्मेंस पर खराब असर पड़ता है. इस पैटर्न का असर फ़र्स्ट कॉन्टेंटफ़ुल पेंट (एफ़सीपी) पर भी पड़ता है. पेज के जिस वर्शन में कुछ भी इनलाइन नहीं है, उसमें एफ़सीपी करीब 2.7 सेकंड का होता है. जिस वर्शन में सब कुछ इनलाइन है, उसमें एफ़सीपी करीब 5.8 सेकंड का होता है.

एचटीएमएल में चीज़ों को इनलाइन करते समय सावधानी बरतें. खास तौर पर, base64 कोड में बदले गए संसाधनों को. आम तौर पर, हम ऐसा करने का सुझाव नहीं देते. हालांकि, बहुत छोटे संसाधनों को इस्तेमाल करने का सुझाव दिया जाता है. जितना हो सके उतना कम इनलाइन करें, क्योंकि बहुत ज़्यादा इनलाइन करना आग से खेल रहा है.

क्लाइंट-साइड JavaScript की मदद से मार्कअप रेंडर करना

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

क्लाइंट-साइड JavaScript का इस्तेमाल करके मार्कअप को रेंडर करने से, प्रीलोड स्कैनर को गच्चा दिया जा सकता है:

WebPageTest नेटवर्क वॉटरफ़ॉल में, क्लाइंट पर JavaScript में रेंडर की गई इमेज और टेक्स्ट वाला बेसिक पेज दिखाया गया है. मार्कअप, JavaScript में शामिल होता है. इसलिए, प्रीलोड स्कैनर किसी भी संसाधन का पता नहीं लगा सकता. JavaScript फ़्रेमवर्क को ज़रूरत के मुताबिक ज़्यादा नेटवर्क और प्रोसेसिंग में लगने वाले समय की वजह से, सभी संसाधनों को लोड होने में ज़्यादा समय लगता है.
इमेज. 14: क्लाइंट के रेंडर किए गए वेब पेज का WebPageTest नेटवर्क वॉटरफ़ॉल चार्ट, जो मोबाइल डिवाइस पर सिम्युलेटेड 3G कनेक्शन के ज़रिए Chrome पर चलता है. कॉन्टेंट, JavaScript में शामिल होता है और रेंडर करने के लिए फ़्रेमवर्क का इस्तेमाल करता है. इसलिए, क्लाइंट के रेंडर किए गए मार्कअप में मौजूद इमेज रिसॉर्स, प्रीलोड स्कैनर से छिपा होता है. सर्वर से रेंडर किए गए पेज का अनुभव चित्र 9 में दिखाया गया है.

जब ब्राउज़र में मार्कअप पेलोड को JavaScript में शामिल किया जाता है और पूरी तरह से रेंडर किया जाता है, तो उस मार्कअप में मौजूद कोई भी संसाधन प्रीलोड स्कैनर के लिए ठीक से नहीं दिखता. इसकी वजह से, ज़रूरी संसाधनों को खोजने में देरी होती है. इससे एलसीपी पर ज़रूर असर पड़ता है. इन उदाहरणों में, सर्वर से रेंडर किए गए उसी तरह के अनुभव के मुकाबले एलसीपी इमेज के अनुरोध में बहुत ज़्यादा देरी होती है जिसके लिए JavaScript के दिखने की ज़रूरत नहीं होती.

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

इस समस्या को ठीक करने का तरीका, इस सवाल के जवाब पर निर्भर करता है: क्या कोई वजह है कि सर्वर, क्लाइंट पर रेंडर किए जाने के बजाय आपके पेज का मार्कअप नहीं दे पाता? अगर इसका जवाब "नहीं" है, तो जहां भी हो सके वहां सर्वर-साइड रेंडरिंग (एसएसआर) या स्टैटिक तौर पर जनरेट किए गए मार्कअप का इस्तेमाल किया जाना चाहिए. इससे, प्रीलोड स्कैनर को समय से पहले ज़रूरी संसाधनों को खोजने और फ़ेच करने में मदद मिलेगी.

अगर आपके पेज के मार्कअप के कुछ हिस्सों में फ़ंक्शन जोड़ने के लिए JavaScript की ज़रूरत है, तब भी एसएसआर की मदद से ऐसा किया जा सकता है. इसके लिए, वनीला JavaScript या हाइड्रेशन का इस्तेमाल करें. इससे, दोनों तरीकों का बेहतर तरीके से इस्तेमाल किया जा सकेगा.

प्रीलोड स्कैनर की मदद पाना

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

आपको याद दिला दें कि इस पोस्ट में आपको इन बातों का ध्यान रखना होगा:

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

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

संसाधन

Unsplash से ली गई हीरो इमेज, जिसे मोहम्मद रहमानी ने बनाया है .