Vidéo à chargement différé

Comme pour les éléments image, vous pouvez également effectuer un chargement différé de la vidéo. Les vidéos sont généralement chargées avec l'élément <video> (bien qu'une autre méthode utilisant <img> ait émergé avec une implémentation limitée). Toutefois, le mode de chargement différé de <video> dépend du cas d'utilisation. Étudions quelques scénarios nécessitant chacun une solution différente.

Vidéo sans lecture automatique

Pour les vidéos dont la lecture est lancée par l'utilisateur (c'est-à-dire les vidéos qui ne sont pas lues automatiquement), il peut être souhaitable de spécifier l'attribut preload sur l'élément <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>

L'exemple ci-dessus utilise un attribut preload avec la valeur none pour empêcher les navigateurs de précharger des données vidéo. L'attribut poster donne à l'élément <video> un espace réservé qui occupera l'espace pendant le chargement de la vidéo. La raison à cela est que les comportements par défaut pour le chargement de vidéos peuvent varier d'un navigateur à l'autre:

  • Dans Chrome, la valeur par défaut de preload était auto, mais à partir de Chrome 64, elle est désormais metadata. Néanmoins, dans la version classique de Chrome, une partie de la vidéo peut être préchargée à l'aide de l'en-tête Content-Range. Les autres navigateurs Chromium et Firefox se comportent de la même manière.
  • Comme pour Chrome sur ordinateur, les versions pour ordinateur 11.0 de Safari préchargent certaines vidéos. À partir de la version 11.2, seules les métadonnées de la vidéo sont préchargées. Dans Safari sur iOS, les vidéos ne sont jamais préchargées.
  • Lorsque le mode Économiseur de données est activé, preload est défini par défaut sur none.

Étant donné que les comportements par défaut des navigateurs concernant preload ne sont pas figés, il est probablement préférable d'être explicite. Dans ce cas, lorsque l'utilisateur lance la lecture, l'utilisation de preload="none" est le moyen le plus simple de différer le chargement de la vidéo sur toutes les plates-formes. L'attribut preload n'est pas le seul moyen de différer le chargement d'un contenu vidéo. La section Lecture rapide avec préchargement de vidéos peut vous donner des idées et des informations sur l'utilisation de la lecture de vidéos en JavaScript.

Malheureusement, cela ne s'avère pas utile lorsque vous souhaitez utiliser des vidéos à la place des GIF animés, dont nous allons parler ensuite.

Pour une vidéo remplaçant un GIF animé

Bien que les GIF animés soient largement utilisés, ils sont inférieurs aux équivalents vidéo à plusieurs égards, notamment en termes de taille de fichier. Les GIF animés peuvent s'étendre à plusieurs mégaoctets de données. Les vidéos de qualité visuelle similaire ont tendance à être bien plus petites.

L'utilisation de l'élément <video> pour remplacer un GIF animé n'est pas aussi simple que l'élément <img>. Les GIF animés présentent trois caractéristiques:

  1. Elles sont lues automatiquement une fois chargées.
  2. Elles sont lues en boucle en continu (mais ce n'est pas toujours le cas).
  3. Elles n'ont pas de piste audio.

Pour ce faire, utilisez l'élément <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>

Les attributs autoplay, muted et loop sont explicites. playsinline est nécessaire pour que la lecture automatique ait lieu sur iOS. Vous disposez désormais d'un remplacement vidéo-GIF pouvant être utilisé et compatible avec toutes les plates-formes. Mais comment procéder à un chargement différé ? Pour commencer, modifiez votre balisage <video> en conséquence:

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

Vous remarquerez l'ajout de l'attribut poster, qui vous permet de spécifier un espace réservé pour occuper l'espace de l'élément <video> jusqu'à ce que le chargement de la vidéo soit différé. Comme pour les exemples de chargement différé <img>, stockez l'URL de la vidéo dans l'attribut data-src de chaque élément <source>. Ensuite, utilisez un code JavaScript semblable aux exemples de chargement différé d'image basé sur 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);
    });
  }
});

Lorsque vous chargez un élément <video> de manière différée, vous devez itérer tous les éléments <source> enfants et convertir leurs attributs data-src en attributs src. Une fois cette opération effectuée, vous devez déclencher le chargement de la vidéo en appelant la méthode load de l'élément. La lecture du contenu multimédia commencera alors automatiquement en fonction de l'attribut autoplay.

Avec cette méthode, vous disposez d'une solution vidéo qui émule le comportement des GIF animés, mais qui n'engendre pas la même consommation de données intensive que les GIF animés. Vous pouvez charger ce contenu en différé.

Bibliothèques à chargement différé

Les bibliothèques suivantes peuvent vous aider à charger des vidéos de manière différée:

  • vanilla-lazyload et lozad.js sont des options très légères qui n'utilisent qu'Intersection Observer. Ils sont donc très performants, mais ils devront être émulés avant de pouvoir être utilisés dans des navigateurs plus anciens.
  • yall.js est une bibliothèque qui utilise Intersection Observer et se rabat sur les gestionnaires d'événements. Il peut également charger des images poster vidéo de façon différée à l'aide d'un attribut data-poster.
  • Si vous avez besoin d'une bibliothèque de chargement différé spécifique à React, vous pouvez envisager d'utiliser react-lazyload. Bien qu'il n'utilise pas Intersection Observer, il fournit une méthode de chargement différé des images familière, destinée aux personnes habituées au développement d'applications avec React.

Chacune de ces bibliothèques de chargement différé est bien documentée, avec de nombreux modèles de balisage pour vos différents types de chargements différés.