Learn Performance - Video

GIF replacement

To avoid downloading all the videos on a page, it is possible to configure an Intersection Observer to only download videos once they appear in the viewport.

The <video> element uses the preload attribute to prevent the browser from downloading the file immediately. When the video appears in the viewport, it is set then set to autoplay - at which point the video begins downloading.

The poster attribute is used to show the first frame of the video to improve the perceived performance.

View Source Code
// index.html
<video
  class="lazy"
  preload="none"
  muted
  controls
  loop
  playsinline
  width="640"
  height="1138"
  poster="https://cdn.glitch.global/97616b87-f930-4eb0-a8a0-84c6a73d97e7/gif-1.jpg?v=1671616580215"
>
  <source
    src="https://cdn.glitch.global/97616b87-f930-4eb0-a8a0-84c6a73d97e7/gif-1.webm?v=1671616580215"
    type="video/webm"
  />
  <source
    src="https://cdn.glitch.global/97616b87-f930-4eb0-a8a0-84c6a73d97e7/gif-1.mp4?v=1671616580215"
    type="video/mp4"
  />
</video>


// script.js
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.autoplay = true;
          video.target.controls = false;
          video.target.load();
          lazyVideoObserver.unobserve(video.target);
        }
      });
    });

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