लेज़ी लोडिंग वीडियो

पब्लिश करने की तारीख: 16 अगस्त, 2019

इमेज एलिमेंट की तरह, वीडियो को भी धीरे-धीरे लोड किया जा सकता है. आम तौर पर, वीडियो <video> एलिमेंट के साथ लोड किए जाते हैं. हालांकि, YouTube जैसी अन्य सेवाओं पर होस्ट किए गए वीडियो के लिए, <iframe> का इस्तेमाल किया जा सकता है. ऐसे में, लेज़ी-लोडिंग iframes लेख पढ़ें.

<video> को लेज़ी-लोड करने का तरीका, इस्तेमाल के उदाहरण पर निर्भर करता है. ऐसा इसलिए, क्योंकि इसके लिए कुछ अलग-अलग तरीके उपलब्ध हैं.

आम तौर पर, वीडियो अपने-आप चलने की सुविधा बंद रखना सबसे सही होता है. इससे उपयोगकर्ता के पास वीडियो चलाने का कंट्रोल रहता है. इन मामलों में, पूरे वीडियो को लोड होने से रोकने का सबसे अच्छा तरीका यह है कि <video> एलिमेंट पर preload एट्रिब्यूट की वैल्यू सबमिट की जाए:

<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

पिछले उदाहरण में, preload एट्रिब्यूट का इस्तेमाल किया गया है. इसकी वैल्यू none है. इससे ब्राउज़र, किसी भी वीडियो डेटा को पहले से लोड नहीं कर पाते. poster एट्रिब्यूट, <video> एलिमेंट को एक प्लेसहोल्डर देता है. यह प्लेसहोल्डर, वीडियो लोड होने के दौरान उस जगह को भर देगा.

ज़्यादातर ब्राउज़र में preload डिफ़ॉल्ट रूप से metadata पर सेट होता है. साथ ही, Content-Range हेडर का इस्तेमाल करके वीडियो का एक हिस्सा पहले से लोड हो जाता है. इस वजह से, ज़रूरत से ज़्यादा डेटा डाउनलोड हो सकता है. ऐसा खास तौर पर तब होता है, जब ब्राउज़र में Content-Range हेडर काम न करता हो. इस सुविधा के काम करने के बावजूद, ब्राउज़र यह नहीं जान सकते कि मेटाडेटा किन बाइट में सेव किया गया है. ऐसा हो सकता है कि इसे फ़ाइल की शुरुआत में सेव न किया गया हो. इसलिए, वीडियो लोड होने से रोकने के लिए, none की वैल्यू तय करें और preload="none" का इस्तेमाल करें.

इस सुविधा को और बेहतर बनाया जा सकता है, ताकि जब कोई उपयोगकर्ता onmouseenter एट्रिब्यूट वाले वीडियो पर कर्सर घुमाए, तो मेटाडेटा को पहले से लोड किया जा सके. इसके लिए, mouseenter इवेंट हैंडलर का इस्तेमाल किया जा सकता है:

<video controls
  preload="none"
  poster="one-does-not-simply-placeholder.jpg"
  onmouseenter="event.target.setAttribute('preload','metadata')">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

इससे, वीडियो चलाने में लगने वाला समय कम हो जाता है. साथ ही, वीडियो चलाने पर उसे चलाने का कुल समय भी तुरंत दिखने लगता है.

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

<link rel="preload" href="one-does-not-simply-placeholder.jpg" as="image" fetchpriority="high">
<video controls preload="none"
  poster="one-does-not-simply-placeholder.jpg"
  onmouseenter="event.target.setAttribute('preload','metadata')">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

ऐनिमेटेड GIF की जगह वीडियो का इस्तेमाल करने के लिए

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

ऐनिमेशन वाले GIF की जगह <video> एलिमेंट का इस्तेमाल करना, <img> एलिमेंट के मुकाबले आसान नहीं है. ऐनिमेटेड GIF में ये तीन चीज़ें होती हैं:

  1. ये लोड होने पर अपने-आप चलने लगते हैं.
  2. वे लगातार लूप में चलते रहते हैं (हालांकि, ऐसा हमेशा नहीं होता).
  3. उनमें कोई ऑडियो ट्रैक न हो.

<video> एलिमेंट की मदद से ऐसा करने पर, यह कुछ ऐसा दिखता है:

<video autoplay muted loop playsinline>
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

autoplay, muted, और loop एट्रिब्यूट के बारे में अपने-आप जानकारी मिल जाती है. iOS में वीडियो अपने-आप चलने के लिए, playsinline की ज़रूरत होती है. अब आपके पास GIF के तौर पर वीडियो बदलने की सुविधा है, जो सभी प्लैटफ़ॉर्म पर काम करती है. लेकिन इसे लेज़ी लोड कैसे करें? शुरू करने के लिए, अपने <video> मार्कअप में इन बदलावों को करें:

<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
  <source data-src="one-does-not-simply.webm" type="video/webm">
  <source data-src="one-does-not-simply.mp4" type="video/mp4">
</video>

आपको poster एट्रिब्यूट दिखेगा. इसकी मदद से, वीडियो के लेज़ी-लोड होने तक <video> एलिमेंट के स्पेस में प्लेसहोल्डर जोड़ा जा सकता है. <img> लेज़ी-लोडिंग के उदाहरणों की तरह ही, हर <source> एलिमेंट के data-src एट्रिब्यूट में वीडियो का यूआरएल डालें. इसके बाद, इंटरसेक्शन ऑब्ज़र्वर पर आधारित इमेज को लेज़ी लोड करने के उदाहरणों की तरह ही JavaScript कोड का इस्तेमाल करें:

document.addEventListener("DOMContentLoaded", function() {
  var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));

  if ("IntersectionObserver" in window) {
    var lazyVideoObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(video) {
        if (video.isIntersecting) {
          for (var source in video.target.children) {
            var videoSource = video.target.children[source];
            if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
              videoSource.src = videoSource.dataset.src;
            }
          }

          video.target.load();
          video.target.classList.remove("lazy");
          lazyVideoObserver.unobserve(video.target);
        }
      });
    });

    lazyVideos.forEach(function(lazyVideo) {
      lazyVideoObserver.observe(lazyVideo);
    });
  }
});

किसी <video> एलिमेंट को लेज़ी-लोड करने पर, आपको सभी चाइल्ड <source> एलिमेंट को दोहराना होगा और उनके data-src एट्रिब्यूट को src एट्रिब्यूट में बदलना होगा. इसके बाद, आपको एलिमेंट के load तरीके को कॉल करके, वीडियो लोड होने की प्रोसेस को ट्रिगर करना होगा. इसके बाद, मीडिया autoplay एट्रिब्यूट के हिसाब से अपने-आप चलने लगेगा.

इस तरीके का इस्तेमाल करके, आपको एक ऐसा वीडियो विकल्प मिलता है जो ऐनिमेटेड GIF की तरह काम करता है. हालांकि, इसमें ऐनिमेटेड GIF की तरह ज़्यादा डेटा का इस्तेमाल नहीं होता. साथ ही, इस कॉन्टेंट को लेज़ी-लोड किया जा सकता है.

लेज़ी लोडिंग लाइब्रेरी

इन लाइब्रेरी की मदद से, वीडियो को धीरे-धीरे लोड किया जा सकता है:

  • vanilla-lazyload और lozad.js, बहुत कम साइज़ वाले विकल्प हैं. ये सिर्फ़ इंटरसेक्शन ऑब्ज़र्वर का इस्तेमाल करते हैं. इसलिए, ये ऐप्लिकेशन बेहतर परफ़ॉर्म करते हैं. हालांकि, पुराने ब्राउज़र पर इनका इस्तेमाल करने से पहले, उन्हें पॉलीफ़िल करना होगा.
  • yall.js एक लाइब्रेरी है, जो इंटरसेक्शन ऑब्ज़र्वर का इस्तेमाल करती है और इवेंट हैंडलर पर फ़ॉलबैक करती है. यह data-poster एट्रिब्यूट का इस्तेमाल करके, वीडियो poster इमेज को भी धीरे-धीरे लोड कर सकता है.
  • अगर आपको React के लिए खास तौर पर बनी, धीरे-धीरे लोड होने वाली लाइब्रेरी की ज़रूरत है, तो react-lazyload का इस्तेमाल करें. हालांकि, इसमें इंटरसेक्शन ऑब्ज़र्वर का इस्तेमाल नहीं किया जाता, लेकिन React का इस्तेमाल करके ऐप्लिकेशन डेवलप करने वाले लोगों के लिए, यह इमेज को लेज़ी लोड करने का जाना-पहचाना तरीका देता है.

इनमें से हर एक लाइब्रेरी के बारे में अच्छी तरह से जानकारी दी गई है. साथ ही, इनमें लेज़ी लोडिंग के लिए कई मार्कअप पैटर्न मौजूद हैं.