Lazy Load วิดีโอ YouTube โดยใช้ IntersectionObserver และ YouTube API

Jan 27 2023
ปัญหา: เมื่อโหลดหน้าเว็บ เบราว์เซอร์จำเป็นต้องดาวน์โหลดและแยกวิเคราะห์สคริปต์และทรัพยากรอื่นๆ ที่ใช้โดยหน้าเว็บทั้งหมดก่อนที่จะแสดงผลได้อย่างสมบูรณ์ หากหน้าเว็บมีสคริปต์จำนวนมาก หรือหากสคริปต์มีขนาดใหญ่ อาจทำให้โหลดหน้าเว็บล่าช้าได้
Lazy Load YouTube API โดยใช้ IntersectionObserver

ปัญหา:

เมื่อโหลดหน้าเว็บ เบราว์เซอร์จำเป็นต้องดาวน์โหลดและแยกวิเคราะห์สคริปต์และทรัพยากรอื่นๆ ที่ใช้โดยหน้าเว็บก่อนที่จะแสดงผลได้อย่างสมบูรณ์ หากหน้าเว็บมีสคริปต์จำนวนมาก หรือหากสคริปต์มีขนาดใหญ่ อาจทำให้โหลดหน้าเว็บล่าช้าได้

ในกรณีของสคริปต์ API ของ YouTube ( base.js , www-embed-player.jsและwww-widgetapi.js ) สคริปต์เหล่านี้เป็นไฟล์ที่ค่อนข้างใหญ่ซึ่งเบราว์เซอร์จำเป็นต้องโหลดและแยกวิเคราะห์ก่อนที่หน้าเว็บจะเต็มได้ แสดงผล หากหน้าเว็บมีวิดีโอ YouTube จำนวนมาก การโหลดสคริปต์ API ของ YouTube สำหรับวิดีโอแต่ละรายการสามารถเพิ่มเวลาในการโหลดหน้าเว็บได้อย่างมาก สิ่งนี้อาจส่งผลเสียต่อประสบการณ์ของผู้ใช้ เนื่องจากผู้ใช้อาจต้องรอนานเพื่อให้หน้าโหลด

ปัญหาอีกประการหนึ่งในการโหลดสคริปต์ API ของ YouTube คืออาจทำให้ขนาดโดยรวมของหน้าเว็บเพิ่มขึ้น ซึ่งอาจทำให้เวลาในการโหลดนานขึ้น โดยเฉพาะสำหรับผู้ใช้ที่มีการเชื่อมต่ออินเทอร์เน็ตที่ช้าลง

นอกจากนี้ ข้อกำหนดในการให้บริการของ YouTube API ยังเข้มงวดกับวิดีโอที่เล่นอัตโนมัติ ดังนั้นโปรดปฏิบัติตามหลักเกณฑ์เพื่อหลีกเลี่ยงปัญหาใดๆ

เพื่อลดปัญหาเหล่านี้ นักพัฒนาสามารถใช้เทคนิคต่างๆ เช่น การโหลดแบบขี้เกียจ การโหลดแบบอะซิงโครนัส การแคช และการโหลด API เมื่อจำเป็นเท่านั้น เช่นเดียวกับการลดขนาดสคริปต์เพื่อลดขนาดและปรับปรุงเวลาในการโหลดหน้าเว็บ

มีสองสามวิธีในการบรรเทาปัญหานี้:

  1. การโหลดแบบ Lazy Loading:แทนที่จะโหลดสคริปต์ API ของ YouTube ในการโหลดหน้าเว็บ คุณสามารถใช้การโหลดแบบ Lazy Loading ได้โดยใช้ API IntersectionObserverเพื่อตรวจจับเมื่อองค์ประกอบวิดีโออยู่ในวิวพอร์ต จากนั้นจึงโหลดสคริปต์ API
  2. การโหลดแบบอะซิงโครนัส:คุณสามารถใช้asyncแอตทริบิวต์บนแท็กสคริปต์เพื่อโหลดสคริปต์ API ของ YouTube แบบอะซิงโครนัส ซึ่งช่วยให้เบราว์เซอร์สามารถแยกวิเคราะห์ส่วนที่เหลือของหน้าต่อไปได้ในขณะที่สคริปต์กำลังโหลดอยู่เบื้องหลัง ซึ่งสามารถปรับปรุงเวลาในการโหลดโดยรวมของหน้าได้
  3. การแคช:อีกวิธีในการเพิ่มความเร็วในการโหลดเว็บไซต์ของคุณคือการใช้แคช ด้วยการแคชสคริปต์ API ของ YouTube เบราว์เซอร์ไม่จำเป็นต้องดาวน์โหลดไฟล์เดียวกันหลายครั้ง ซึ่งช่วยลดเวลาในการโหลด
  4. โหลด API เมื่อจำเป็นเท่านั้น:หากคุณใช้ YouTube API เฉพาะในหน้าหรือบางส่วนของเว็บไซต์ของคุณ คุณจะโหลด API ได้เมื่อจำเป็นเท่านั้น เช่น เมื่อผู้ใช้คลิกปุ่มหรือลิงก์ที่ต้องการ
  5. ย่อขนาดสคริปต์:ย่อขนาดสคริปต์เป็นกระบวนการลบอักขระที่ไม่จำเป็นออกจากโค้ด เช่น ช่องว่าง ความคิดเห็น และขึ้นบรรทัดใหม่ เพื่อลดขนาดของไฟล์ สิ่งนี้สามารถช่วยเพิ่มความเร็วในการโหลดสคริปต์

IntersectionObserverสามารถใช้ API เพื่อโหลดวิดีโอ YouTube หลายรายการแบบ Lazy Loading บนหน้าเว็บโดยสังเกตองค์ประกอบวิดีโอแต่ละรายการแยกจากกัน

ต่อไปนี้เป็นตัวอย่างของวิธีใช้IntersectionObserverAPI เพื่อโหลดวิดีโอ YouTube หลายรายการแบบ Lazy Loading:

HTML:

<div class="video-container">
  <div class="autoplayer" data-video="video1_id"></div>
  <div class="autoplayer" data-video="video2_id"></div>
  <div class="autoplayer" data-video="video3_id"></div>
</div>

ขั้นแรก ให้เพิ่มโค้ดนี้เพื่อเลือกองค์ประกอบวิดีโอทั้งหมดที่มีคลาส “เล่นอัตโนมัติ” และสร้างที่IntersectionObserverสังเกตองค์ประกอบวิดีโอแต่ละรายการ

// Get all the video elements
var videoElements = document.querySelectorAll('.autoplayer');

// Create the IntersectionObserver
var observer = new IntersectionObserver(onIntersection);

// Start observing each video element
videoElements.forEach(function (videoElement) {
  observer.observe(videoElement);
});

// Callback function for when the video element is in the viewport
function onIntersection(entries) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      
      // Load the YouTube API scripts
      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      
      // Stop observing the video element
      observer.unobserve(entry.target);
    }
  });
}

function onYouTubePlayerAPIReady() {
  var players = document.querySelectorAll('.autoplayer');
  players.forEach(function (element) {
    let videoId = element.dataset.video;

    let player = new YT.Player(element, {
      videoId: videoId,
      playerVars: {
        autoplay: 1,
        showinfo: 0,
        controls: 0,
        loop: 1,
        enablejsapi: 1,
        rel: 0,
        origin: 'https://localhost/',
      },
      events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
      }
    });

  });
}

function onPlayerReady(event) {
  event.target.mute();
  event.target.playVideo();
}

function onPlayerStateChange(event) {
  if (event.data === 0) {
    event.target.playVideo();
  }
}

คุณยังสามารถเพิ่มตรรกะที่เหลือสำหรับ youtube API และโปรแกรมเล่นวิดีโอภายในฟังก์ชัน onIntersection และตรวจสอบให้แน่ใจว่าคุณมีตัวเลือกที่ถูกต้องสำหรับ videoElements และไม่มีรายการที่ซ้ำกัน

ขอบคุณ!