延迟加载视频

图片



通常,视频是使用video标签上传的(尽管出现了使用img替代方法,但是功能有限)。实施延迟视频加载的方式取决于用例。让我们讨论几种方案,每种方案都需要不同的解决方案。



对于没有自动播放功能的视频



对于用户启动的视频(即无法自动播放的视频),您需要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>


在上面的示例中,使用属性preload的值为none,禁止浏览器下载任何视频数据。poster属性设置视频的预览图像,它将在页面上替换视频,直到加载为止。需要预览是由于以下事实:视频加载在不同的浏览器中有所不同:



  • 在Chrome中,preload属性的默认值为auto,但是从64版开始,默认值为metadata即使这样,在台式机Chrome上,也可以使用Content-Range标头预加载一部分视频。Firefox,Edge和Internet Explorer 11的行为类似。
  • Chrome, Safari 11.0 . 11.2, , Safari iOS .
  • , preload none.


由于默认行为在不同的浏览器中在自动加载方面有所不同,因此最好最好是显式设置此行为。如果用户自行启动播放,则使用preload =“ none”是在所有平台上延迟视频加载的最简单方法。preload属性不是延迟视频内容加载的唯一方法。通过视频预加载进行快速播放可以为您提供一些思路和见解,帮助您在JavaScript中使用视频播放。



不幸的是,如果您想使用视频而不是GIF,这是没有用的,我们将在下面讨论。



对于用作GIF动画替代品的视频



尽管动画GIF广泛使用,但它们在许多方面都无法与视频等效项匹配,特别是在文件大小方面。动画GIF可能占用数兆字节的数据。具有相似视觉质量的视频通常要小得多。



视频元素代替动画GIF并不容易。动画GIF具有三个特征:



  1. 下载后它们会自动播放。
  2. 它们不断循环(尽管并非总是如此)。
  3. 他们没有音轨。


使用视频标签实现此目标看起来像这样:



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


自动播放静音循环 属性是不言自明的。在iOS上自动播放需要playinline。现在,您可以使用可用的视频动画替换。但是,如何为视频添加延迟加载?Chrome的延迟加载视频加载没有问题,但是您不能指望所有浏览器都能提供这种优化的行为。根据您的受众和应用程序要求,您可能需要自己处理问题。首先,让我们更改视频连接:



<video 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标签,直到视频被延迟加载。视频URL放置在每个source元素data-src属性中 我们使用JavaScript使用IntersectionObserver来组织“延迟”加载。







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


我们遍历source的所有子元素,并将其data-src属性转换src属性完成此操作后,您需要通过调用load方法开始加载视频,此后,媒体将根据autoplay属性自动开始播放



通过使用此方法,您可以获得模仿动画GIF的行为的现成视频解决方案,但不需要相同的大量数据使用,因此可以延迟加载此内容。



延迟加载库



以下库可以帮助您进行延迟视频加载:



  • lozad.js是仅使用Intersection Observer的超轻量级版本。因此,它非常有效,但是您需要先使用polyfill对其进行补充,然后才能在较旧的浏览器中使用它。
  • yall.js是一个使用Intersection Observer并访问事件处理程序的库。它与IE11和主要浏览器兼容。
  • 如果需要React的lazyload库,可以考虑react-lazyload这个库没有使用Intersection Observer,但是提供了一种延迟加载图像的方法,这是React开发人员会熟悉的。


这些库中的每一个都有文档记录,并且包含许多用于各种延迟加载任务的标记模板。



All Articles