Vidéo à chargement différé

Vous pouvez également effectuer le chargement différé des vidéos, comme pour les éléments image. Les vidéos sont généralement chargées avec l'élément <video> (même si une autre méthode utilisant <img> a émergé avec une implémentation limitée). La méthode de chargement différé de <video> dépend toutefois du cas d'utilisation. Examinons deux scénarios qui nécessitent chacun une solution différente.

Pour les vidéos sans lecture automatique

Pour les vidéos dont la lecture est lancée par l'utilisateur (c'est-à-dire celles 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 aucune donnée vidéo. L'attribut poster donne à l'élément <video> un espace réservé qui occupera cet espace pendant le chargement de la vidéo. En effet, les comportements par défaut de chargement des vidéos peuvent varier d'un navigateur à l'autre:

  • Dans Chrome, la valeur par défaut de preload était auto, mais depuis Chrome 64, elle est désormais metadata. Même dans ce cas, dans la version pour ordinateur 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 basés sur Chromium et Firefox se comportent de la même manière.
  • Comme avec Chrome pour ordinateur, les versions pour ordinateur 11.0 de Safari préchargent une partie de la vidéo. Depuis 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 du navigateur concernant preload ne sont pas figés, il est probablement préférable d'être explicite. Dans les cas où 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 du contenu vidéo. L'article Fast Playback with Video Preload (Lecture rapide avec préchargement vidéo) peut vous donner des idées et des informations pour utiliser la lecture de vidéos en JavaScript.

Malheureusement, cela ne s'avère pas utile lorsque vous souhaitez utiliser une vidéo à la place des GIF animés, comme nous le verrons ci-après.

Pour une vidéo servant de remplacement de GIF animé

Bien que les GIF animés soient largement utilisés, ils sont inférieurs aux équivalents vidéo à plusieurs égards, en particulier en ce qui concerne la taille de fichier. Les GIF animés peuvent s’étendre sur plusieurs mégaoctets de données. Les vidéos de qualité visuelle similaire ont tendance à être beaucoup plus petites.

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

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

L'élément <video> permet d'atteindre cet objectif:

<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 s'effectue sur iOS. Vous disposez désormais d'un remplacement de vidéo en tant que GIF exploitable qui fonctionne sur toutes les plates-formes. Mais comment procéder au chargement différé ? Pour commencer, modifiez le 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 la vidéo soit chargée en différé. Comme pour les exemples de chargement différé <img>, placez l'URL de la vidéo dans l'attribut data-src de chaque élément <source>. À partir de là, 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> en différé, vous devez itérer tous les éléments enfants <source> et transformer 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 selon l'attribut autoplay.

À l'aide de 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 utilisation intensive de données que les GIF animés, et vous permet de charger ce contenu de manière différée.

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. Elles sont donc très performantes, mais devront être émulées avant de pouvoir les utiliser sur des navigateurs plus anciens.
  • yall.js est une bibliothèque qui utilise Intersection Observer et des gestionnaires d'événements. Il peut également charger des images vidéo poster de manière 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 familière de chargement différé des images pour les personnes habituées au développement d'applications avec React.

Chacune de ces bibliothèques de chargement différé est bien documentée et propose de nombreux modèles de balisage pour vos différentes opérations de chargement différé.