लेज़ी लोडिंग के सबसे सही तरीके

लेज़ी लोडिंग वाली इमेज और वीडियो की परफ़ॉर्मेंस, अच्छी और मापी जा सकती है. हालांकि, इसे हल्के में लेने की ज़रूरत नहीं है. अगर आपको गलत जानकारी मिलती है, तो अनचाहे नतीजे मिल सकते हैं. इसलिए, इन समस्याओं को ध्यान में रखना ज़रूरी है.

फ़ोल्ड के लिए ध्यान दें

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

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

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

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

let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
  // lazy-loading image code goes here
}, {
  rootMargin: "0px 0px 256px 0px"
});

अगर rootMargin की वैल्यू, सीएसएस margin प्रॉपर्टी के लिए तय की गई वैल्यू से मिलती-जुलती है, तो ऐसा इसलिए है, क्योंकि ऐसा है! इस मामले में, मॉनिटर किए गए एलिमेंट के निचले मार्जिन (डिफ़ॉल्ट रूप से ब्राउज़र व्यूपोर्ट, लेकिन root प्रॉपर्टी का इस्तेमाल करके इसे किसी खास एलिमेंट में बदला जा सकता है) का मार्जिन 256 पिक्सल तक बढ़ाया जाता है. इसका मतलब है कि कॉलबैक फ़ंक्शन तब लागू होगा, जब कोई इमेज एलिमेंट व्यूपोर्ट के 256 पिक्सल के अंदर होगा और उपयोगकर्ता को इमेज देखने से पहले ही इमेज लोड होने लगेगी.

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

लेआउट शिफ़्टिंग और प्लेसहोल्डर

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

<img> टैग के लिए, src को शुरू में प्लेसहोल्डर पर ले जाना चाहिए. ऐसा तब तक करना चाहिए, जब तक उस एट्रिब्यूट को फ़ाइनल इमेज यूआरएल के साथ अपडेट नहीं किया जाता. प्लेसहोल्डर इमेज पर ले जाने के लिए, <video> एलिमेंट में poster एट्रिब्यूट का इस्तेमाल करें. इसके अलावा, <img> और <video>, दोनों टैग के लिए width और height एट्रिब्यूट का इस्तेमाल करें. इससे यह पक्का होता है कि प्लेसहोल्डर से फ़ाइनल इमेज में ट्रांज़िशन करने पर, मीडिया लोड होने पर एलिमेंट का रेंडर किया गया साइज़ नहीं बदलेगा.

इमेज डिकोड करने में देरी

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

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

if ("decode" in newImage) {
  // Fancy decoding logic
  newImage.decode().then(function() {
    imageContainer.appendChild(newImage);
  });
} else {
  // Regular image load
  imageContainer.appendChild(newImage);
}

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

कॉन्टेंट लोड न होने पर

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

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

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

newImage.onerror = function(){
  // Decide what to do on error
};
newImage.onload = function(){
  // Load the image
};

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

ऐसी दूसरी स्थितियां भी सामने आ सकती हैं. आप चाहे कुछ भी करें, लेकिन कोई भी गड़बड़ी होने पर, उपयोगकर्ता को सिग्नल देने से पहले उसकी मदद की जा सकती है. साथ ही, कुछ गड़बड़ी होने पर उसे कार्रवाई करने के लिए बढ़ावा दिया जा सकता है.

JavaScript की उपलब्धता

यह नहीं माना जाना चाहिए कि JavaScript हमेशा उपलब्ध है. अगर आपको लेज़ी-लोड वाली इमेज इस्तेमाल करनी हैं, तो <noscript> मार्कअप उपलब्ध कराएं. इससे, JavaScript उपलब्ध न होने पर भी इमेज दिखेंगी. फ़ॉलबैक के सबसे आसान उदाहरण में, JavaScript बंद होने पर इमेज दिखाने के लिए <noscript> एलिमेंट का इस्तेमाल करना शामिल है:

मैं एक इमेज हूं!

अगर JavaScript बंद है, तो उपयोगकर्ताओं को प्लेसहोल्डर इमेज और <noscript> एलिमेंट वाली इमेज दोनों दिखेंगी. इसके बारे में जानने के लिए, <html> टैग पर no-js की क्लास इस तरह डालें:

<html class="no-js">

इसके बाद, किसी भी स्टाइल शीट का अनुरोध <link> टैग के ज़रिए किए जाने से पहले, <head> में इनलाइन स्क्रिप्ट की एक लाइन डालें. अगर JavaScript चालू है, तो यह <html> एलिमेंट से no-js क्लास को हटा देती है:

<script>document.documentElement.classList.remove("no-js");</script>

आखिर में, JavaScript उपलब्ध न होने पर लेज़ी क्लास वाले एलिमेंट को छिपाने के लिए, कुछ सीएसएस का इस्तेमाल करें:

.no-js .lazy {
  display: none;
}

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