অলস লোডিং ভিডিও

প্রকাশিত: ১৬ আগস্ট, ২০১৯, সর্বশেষ হালনাগাদ: ২ জুলাই, ২০২৬

ইমেজ এলিমেন্টের মতোই, আপনি ভিডিও-ও লেজি-লোড করতে চাইতে পারেন। ভিডিও সাধারণত <video> এলিমেন্ট দিয়ে লোড করা হয়, যদিও ইউটিউবের মতো অন্যান্য সার্ভিসে হোস্ট করা ভিডিওর ক্ষেত্রে <iframe> ব্যবহার করা হতে পারে (সেক্ষেত্রে iframe লেজি-লোডিং সম্পর্কিত আর্টিকেলটি দেখে নিতে পারেন)।

কীভাবে <video> লেজি-লোড করতে হবে তা ব্যবহারের ধরনের উপর নির্ভর করে, কারণ এর কয়েকটি ভিন্ন সমাধান রয়েছে।

loading অ্যাট্রিবিউট ব্যবহার করে

ব্রাউজারগুলো এখন মিডিয়া এলিমেন্টগুলোতে ( <video> এবং <audio> ) loading অ্যাট্রিবিউট সমর্থন করা শুরু করেছে। যেখানে এটি সমর্থিত, সেখানে শুধু loading="lazy" অ্যাট্রিবিউটটি যোগ করার মাধ্যমেই মিডিয়া এবং যেকোনো পোস্টার ইমেজ স্বয়ংক্রিয়ভাবে লেজি-লোড হয়ে যায়।

<video controls loading="lazy" 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>

loading="lazy" ব্যবহার করলে, ভিউপোর্টের মধ্যে বা কাছাকাছি না আসা পর্যন্ত poster ইমেজটি একেবারেই লোড হবে না এবং এরপর video কতটুকু লোড হবে তা নির্ধারণ করতে preload অ্যাট্রিবিউট ব্যবহার করবে। এর মানে হলো, autoplay ভিডিওগুলোও ভিউপোর্টের মধ্যে বা কাছাকাছি না আসা পর্যন্ত অটোপ্লে হবে না। loading="lazy" অ্যাট্রিবিউটটি poster , preload , এবং autoplay অ্যাট্রিবিউটের সাথে কাজ করে এবং এগুলোর প্রয়োজনীয়তাকে প্রতিস্থাপন করে না।

যেসব ব্রাউজার মিডিয়া এলিমেন্টে loading অ্যাট্রিবিউট সমর্থন করে না, তারা এই অ্যাট্রিবিউটটিকে উপেক্ষা করবে। এর ফলে poster ইমেজটি সঙ্গে সঙ্গে লোড হবে এবং ভিডিওটি preload অ্যাট্রিবিউটের ওপর ভিত্তি করে লোড হবে, যা নিয়ে আমরা পরবর্তীতে আলোচনা করব।

যেসব ভিডিও স্বয়ংক্রিয়ভাবে চলে না, সেগুলোকে লেজি-লোড করতে preload অ্যাট্রিবিউট ব্যবহার করুন।

স্বয়ংক্রিয়ভাবে ভিডিও চালু হওয়া এড়িয়ে চলাই সাধারণত উত্তম, কারণ এতে নিয়ন্ত্রণ ব্যবহারকারীর হাতে থাকে। এইসব ক্ষেত্রে, প্রয়োজন না হওয়া পর্যন্ত পুরো ভিডিওটি লোড হওয়া এড়ানোর সেরা উপায় হলো <video> এলিমেন্টে preload অ্যাট্রিবিউটটি নির্দিষ্ট করে দেওয়া।

<video controls loading="lazy" 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>

পূর্ববর্তী উদাহরণে none ভ্যালু সহ একটি preload অ্যাট্রিবিউট ব্যবহার করা হয়েছে, যা ব্রাউজারকে ভিউপোর্টে থাকা অবস্থাতেও কোনো ভিডিও ডেটা প্রি-লোড করা থেকে বিরত রাখে। poster অ্যাট্রিবিউটটি <video> এলিমেন্টকে একটি প্লেসহোল্ডার প্রদান করে, যা ভিডিও লোড হওয়ার সময় স্থানটি দখল করে থাকবে।

বেশিরভাগ ব্রাউজারে preload ডিফল্টভাবে metadata লোড করে এবং Content-Range হেডার ব্যবহার করে ভিডিওর একটি অংশ প্রিলোড করা হয়। এর ফলে প্রয়োজনের চেয়ে বেশি ডেটা ডাউনলোড হয়ে যেতে পারে—ব্রাউজারগুলো জানতে পারে না মেটাডেটা কোন বাইটে সংরক্ষিত আছে, এবং এটি ফাইলের শুরুতে নাও থাকতে পারে। তাই, ভিডিও লোড হওয়া এড়ানোর সেরা উপায় হলো preload="none" ব্যবহার করা।

ব্যবহারকারী যখন ভিডিওর উপর মাউস হোভার করবে, তখন onmouseenter অ্যাট্রিবিউট (অথবা এর সমতুল্য mouseenter ইভেন্ট হ্যান্ডলার) ব্যবহার করে মেটাডেটা প্রি-লোড করার মাধ্যমে এটিকে আরও উন্নত করা যেতে পারে:

<video controls
  loading="lazy"
  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>

এর ফলে ব্যবহারকারীর ভিডিও চালানোর সময়কার বিলম্ব তো কমেই, সেই সাথে ভিডিওটি চালু করার সাথে সাথেই এর সময়কালও দেখা যায়।

ভিডিও LCP ক্যান্ডিডেট হিসেবে বিবেচিত হতে পারে। একটি poster ইমেজ ভিডিওর চেয়ে দ্রুত লোড হবে, তাই যেখানে এটি একটি LCP ক্যান্ডিডেট, সেখানে আপনার একটি পোস্টার ইমেজ ব্যবহার করা উচিত। তবে, এটিকে "high" fetchpriority অ্যাট্রিবিউট ভ্যালু দিয়ে প্রি-লোডও করা উচিত, কারণ এই লেখাটি লেখার সময় পোস্টার অ্যাট্রিবিউটের জন্য fetchpriority নির্দিষ্ট করা যায় না

<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>

যেসব ভিডিও LCP এলিমেন্ট, সেগুলোতে loading="lazy" ব্যবহার করা উচিত নয় — ঠিক যেমনভাবে LCP ইমেজ ও ভিডিও লেজি লোড করা উচিত নয়

ভিডিওর জন্য অ্যানিমেটেড জিআইএফ প্রতিস্থাপন হিসেবে

জিআইএফ-এর মতো দ্রুত অ্যানিমেশনের জন্য স্বয়ংক্রিয়ভাবে চালু হওয়া ভিডিও সাধারণত ব্যবহৃত হয়। যদিও অ্যানিমেটেড জিআইএফ-এর ব্যাপক ব্যবহার রয়েছে, তবে বিভিন্ন দিক থেকে, বিশেষ করে ফাইলের আকারের দিক থেকে, এগুলো ভিডিওর তুলনায় নিম্নমানের। অ্যানিমেটেড জিআইএফ-এর ফাইলের আকার কয়েক মেগাবাইট পর্যন্ত হতে পারে। একই ধরনের ভিজ্যুয়াল কোয়ালিটির ভিডিওগুলো সাধারণত অনেক ছোট হয়।

অ্যানিমেটেড জিআইএফ-এর বিকল্প হিসেবে <video> এলিমেন্ট ব্যবহার করা <img> এলিমেন্টের মতো ততটা সহজ নয়। অ্যানিমেটেড জিআইএফ-এর তিনটি বৈশিষ্ট্য রয়েছে:

  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>

loading="lazy" অ্যাট্রিবিউটটি ভিউপোর্টের কাছাকাছি না আসা পর্যন্ত ভিডিও লোড হওয়া এড়িয়ে চলে। autoplay , muted , এবং loop অ্যাট্রিবিউটগুলোর নাম থেকেই এর অর্থ বোঝা যায়। iOS-এ অটোপ্লে হওয়ার জন্য playsinline আবশ্যক

এখন আপনার কাছে একটি কার্যকরী ভিডিও-কে-জিআইএফ-এ রূপান্তর করার উপায় আছে যা সব প্ল্যাটফর্মে কাজ করে। কিন্তু এটিকে লেজি লোড করবেন কীভাবে?

যেসব ব্রাউজার এটি সমর্থন করে, তাদের জন্য loading="lazy" হলো সবচেয়ে সহজ বিকল্প:

<video loading="lazy" 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>

অন্যান্য ব্রাউজারে ভিডিওর লেজি-লোডিং সমর্থন করার জন্য আপনাকে জাভাস্ক্রিপ্ট ব্যবহার করতে হবে এবং সেই অনুযায়ী আপনার <video> মার্কআপ পরিবর্তন করতে হবে:

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

আপনি লক্ষ্য করবেন যে autoplay সরিয়ে দেওয়া হয়েছে এবং class="lazy" , preload="none"poster অ্যাট্রিবিউটগুলো যোগ করা হয়েছে, যা আপনাকে <video> এলিমেন্টের জায়গায় একটি প্লেসহোল্ডার নির্দিষ্ট করার সুযোগ দেয়, যতক্ষণ না ভিডিওটি লেজি-লোড হয়। এরপর, আমরা অটোপ্লেয়িং পুনরায় চালু করার জন্য একটি জাভাস্ক্রিপ্ট ইন্টারসেকশন অবজারভার ব্যবহার করি:

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) {
          video.target.removeAttribute('preload');
          video.target.removeAttribute('controls');
          video.target.autoplay = true;
          video.target.classList.remove("lazy");
          lazyVideoObserver.unobserve(video.target);
        }
      });
    });

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

এই পদ্ধতি ব্যবহার করলে, ভিডিওটি ডিফল্টভাবে স্বয়ংক্রিয়ভাবে প্লে হয় না, বরং কেবল তখনই প্লে হয় যখন ইন্টারসেকশন অবজারভার ভিডিওটিকে ভিউপোর্টে প্রবেশ করতে শনাক্ত করে। এছাড়াও, জাভাস্ক্রিপ্ট ব্যর্থ হওয়ার পরিস্থিতিগুলো controls অ্যাট্রিবিউটটি সামাল দেয়। সব মিলিয়ে এর অর্থ হলো, আপনি এমন একটি ভিডিও সলিউশন পাচ্ছেন যা অ্যানিমেটেড জিআইএফ-এর মতো আচরণ করে, কিন্তু অ্যানিমেটেড জিআইএফ-এর মতো বিপুল পরিমাণ ডেটা ব্যবহার করে না, এবং আপনি সেই কন্টেন্টটি লেজি-লোড করতে পারবেন।

লেজি লোডিং লাইব্রেরি

নিম্নলিখিত লাইব্রেরিগুলো আপনাকে ভিডিও লেজি-লোড করতে সাহায্য করতে পারে:

  • vanilla-lazyload এবং lozad.js হলো অত্যন্ত হালকা বিকল্প, যা শুধুমাত্র Intersection Observer ব্যবহার করে। এই কারণে, এগুলি উচ্চ পারফরম্যান্স সম্পন্ন, কিন্তু পুরোনো ব্রাউজারগুলিতে ব্যবহার করার আগে এগুলিকে পলিফিল করতে হবে।
  • আপনার যদি React-এর জন্য নির্দিষ্ট কোনো লেজি লোডিং লাইব্রেরির প্রয়োজন হয়, তাহলে আপনি react-lazyload ব্যবহার করে দেখতে পারেন। যদিও এটি Intersection Observer ব্যবহার করে না, তবুও যারা React দিয়ে অ্যাপ্লিকেশন তৈরি করতে অভ্যস্ত, তাদের জন্য এটি ইমেজ লেজি লোড করার একটি পরিচিত পদ্ধতি প্রদান করে

এই লেজি লোডিং লাইব্রেরিগুলোর প্রত্যেকটিরই বিস্তারিত ডকুমেন্টেশন রয়েছে এবং আপনার বিভিন্ন লেজি লোডিং কার্যক্রমের জন্য প্রচুর মার্কআপ প্যাটার্নও দেওয়া আছে।

যেহেতু আরও বেশি ব্রাউজারে <video> এর জন্য loading অ্যাট্রিবিউটটি উপলব্ধ হচ্ছে, আমরা আশা করি যে বিল্ট-ইন সমাধানগুলির পক্ষে জাভাস্ক্রিপ্ট সমাধানগুলির (লাইব্রেরি সহ) ব্যবহার কমে যাবে, তবে যারা এর চেয়ে বেশি নিয়ন্ত্রণ চান তাদের কথা আলাদা।