Tải chậm video YouTube bằng IntersectionObserver và YouTube API

Jan 27 2023
Vấn đề: Khi tải một trang web, trình duyệt cần tải xuống và phân tích cú pháp tất cả các tập lệnh cũng như các tài nguyên khác được trang sử dụng trước khi có thể hiển thị đầy đủ. Nếu một trang web chứa một số lượng lớn tập lệnh hoặc nếu tập lệnh có kích thước lớn, điều này có thể gây ra sự chậm trễ trong thời gian tải của trang.
Lazy Load YouTube API sử dụng IntersectionObserver

Vấn đề:

Khi tải một trang web, trình duyệt cần tải xuống và phân tích cú pháp tất cả các tập lệnh cũng như các tài nguyên khác được trang sử dụng trước khi có thể hiển thị đầy đủ. Nếu một trang web chứa một số lượng lớn tập lệnh hoặc nếu tập lệnh có kích thước lớn, điều này có thể gây ra sự chậm trễ trong thời gian tải của trang.

Trong trường hợp tập lệnh API YouTube ( base.js , www-embed-player.js và www-widgetapi.js ), chúng là những tệp tương đối lớn cần được trình duyệt tải và phân tích cú pháp trước khi trang có thể hiển thị đầy đủ kết xuất. Nếu một trang web chứa một số lượng lớn video YouTube, việc tải tập lệnh API YouTube cho từng video có thể làm tăng đáng kể thời gian tải của trang. Điều này có thể tác động tiêu cực đến trải nghiệm người dùng, vì người dùng có thể phải chờ một thời gian dài để tải trang.

Một vấn đề khác khi tải tập lệnh API YouTube là nó có thể làm tăng kích thước tổng thể của trang web, điều này có thể dẫn đến thời gian tải lâu hơn, đặc biệt đối với người dùng có kết nối internet chậm hơn.

Ngoài ra, các điều khoản dịch vụ của API YouTube nghiêm ngặt đối với các video tự động phát, vì vậy hãy đảm bảo bạn tuân thủ các nguyên tắc để tránh mọi sự cố.

Để giảm thiểu những sự cố này, nhà phát triển có thể sử dụng các kỹ thuật như tải từng phần, tải không đồng bộ, lưu vào bộ nhớ đệm và chỉ tải API khi cần, cũng như thu nhỏ tập lệnh để giảm kích thước và cải thiện thời gian tải của trang web.

Có một số cách để giảm thiểu vấn đề này:

  1. Tải chậm: Thay vì tải tập lệnh API YouTube khi tải trang, bạn có thể sử dụng tải chậm bằng cách sử dụng API IntersectionObserverđể phát hiện khi phần tử video ở trong chế độ xem và sau đó tải tập lệnh API.
  2. Tải không đồng bộ: Bạn cũng có thể sử dụng asyncthuộc tính trên thẻ tập lệnh để tải tập lệnh API YouTube một cách không đồng bộ. Điều này cho phép trình duyệt tiếp tục phân tích cú pháp phần còn lại của trang trong khi tập lệnh đang tải ở chế độ nền, điều này có thể cải thiện thời gian tải tổng thể của trang.
  3. Bộ nhớ đệm: Một cách khác để tăng tốc thời gian tải trang web của bạn là sử dụng bộ nhớ đệm. Bằng cách lưu vào bộ đệm các tập lệnh API YouTube, trình duyệt không cần tải xuống cùng một tệp nhiều lần, giúp giảm thời gian tải.
  4. Chỉ tải API khi cần: Nếu bạn chỉ đang sử dụng API YouTube trên các trang hoặc phần cụ thể trên trang web của mình, thì bạn chỉ có thể tải API khi cần, chẳng hạn như khi người dùng nhấp vào một nút hoặc liên kết cụ thể.
  5. Giảm thiểu tập lệnh: Giảm thiểu tập lệnh là quá trình loại bỏ các ký tự không cần thiết khỏi mã, như khoảng trắng, nhận xét và ngắt dòng, để giảm kích thước tệp. Điều này có thể giúp tăng tốc thời gian tải tập lệnh.

API IntersectionObservercó thể được sử dụng để tải chậm nhiều video YouTube trên một trang web bằng cách quan sát riêng từng phần tử video.

Dưới đây là ví dụ về cách bạn có thể sử dụng IntersectionObserverAPI để tải chậm nhiều video trên YouTube:

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>

Đầu tiên, thêm mã này để chọn tất cả các phần tử video với lớp “trình phát tự động” và tạo một phần IntersectionObservertử quan sát từng phần tử video.

// 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();
  }
}

Bạn cũng có thể thêm phần logic còn lại cho API youtube và trình phát video bên trong hàm onIntersection, đồng thời đảm bảo rằng bạn có bộ chọn chính xác cho videoElements và không có bộ chọn trùng lặp nào nếu có thể.

Cảm ơn!