延遲載入影片

圖片元素相同,您也可以延遲載入影片。影片通常會與 <video> 元素一起載入 (但 替代方法 <img>有 代勞)。延遲載入 <video> 的方式取決於 具體做法和用途以下將討論幾個情境,每種情境都各自需要 不同的解決方案

非自動播放的影片

使用者主動播放影片 (也就是「使用者」未主動播放影片的影片) 自動播放),請指定 preload 屬性 下列元素適合使用:<video>

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

上述範例使用值為 nonepreload 屬性防止瀏覽器 避免預先載入任何影片資料。poster 屬性會為 <video> 元素提供預留位置,在影片載入時佔用空間。這是因為 載入影片的預設行為會因瀏覽器而異:

  • 在 Chrome 中,preload 過去的預設值是 auto,但自 Chrome 64 版起,現在的預設值 預設值為 metadata。即使在電腦版 Chrome 中 影片可能會透過 Content-Range 標頭預先載入。其他以 Chromium 為基礎的瀏覽器和 Firefox 的運作方式,
  • 和電腦版 Chrome 一樣, Safari 11.0 電腦版的 Safari 會預先載入儲存格範圍 而自 11.2 版起,系統只會預先載入影片中繼資料。iOS 版 Safari 一律不會顯示影片 預先載入的內容
  • 數據節省模式開啟時 已啟用,preload 預設為 none

由於與 preload 相關的瀏覽器預設行為並非初始設定, 明確來說就是最好的處置方式若是使用者啟動 播放時,若要延遲在 YouTube 上載入影片,使用 preload="none" 是最簡單的方法 和所有平台。preload 屬性不是延後載入的唯一方法 同理,快速播放影片 預先載入 一些關於在 JavaScript 中播放影片的建議和見解。

不過,如果您想利用影片取代 以下介紹的 GIF 動畫。

將影片當做 GIF 替換動畫

雖然動畫 GIF 廣受大眾歡迎,但效果不如 特別是檔案大小GIF 動畫可以延伸至 有多少 MB 的資料影像品質差不多的影片 圖像的規模現在也小很多

使用 <video> 元素取代動畫 GIF 的效果並不是 如同 <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>

autoplaymutedloop 屬性應該很容易理解。 必須設定 playsinline,才能在以下時間點自動播放: iOS。現在 可替換且跨平台的維修式影片即 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 屬性中 元素。接著,請使用類似於 Intersection Observer 圖片延遲載入範例:

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-lazyloadlozad.js 是超輕量的選項 只使用 Intersection Observer。因此效能非常出色 必須先以多元方式填入廣告,才能在舊版瀏覽器中使用。
  • yall.js 這個程式庫會使用 Intersection Observer 並改回使用事件處理常式。也可以使用 data-poster 屬性延遲載入影片 poster 圖片。
  • 如果需要 React 專屬的延遲載入程式庫,建議 react-lazyload。期間 並未使用 Intersection Observer,但「確實」提供了熟悉的延遲方法 為習慣使用 React 開發應用程式的人載入映像檔。

每個延遲載入程式庫都有充分記錄,內含大量標記 定義各種延遲載入項目