טעינה מדורגת של סרטון

בדומה לרכיבי תמונה, אפשר גם לבצע טעינה מדורגת של סרטונים. סרטונים נטענים בדרך כלל עם הרכיב <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>

בדוגמה שלמעלה נעשה שימוש במאפיין preload עם הערך none כדי למנוע מדפדפנים לטעון מראש נתוני וידאו כלשהם. המאפיין poster מקצה לרכיב <video> placeholder שתפוס את הרווח בזמן שהסרטון נטען. הסיבה לכך היא שפעולות ברירת המחדל לטעינת סרטונים יכולות להשתנות מדפדפן לדפדפן:

  • ב-Chrome, ברירת המחדל של preload הייתה auto, אבל ב-Chrome 64 ברירת המחדל היא metadata. למרות זאת, בגרסת Chrome למחשב, יכול להיות שחלק מהסרטון ייטען מראש באמצעות הכותרת Content-Range. דפדפנים אחרים המבוססים על Chromium ו-Firefox מתנהגים באופן דומה.
  • כמו ב-Chrome במחשב, גם ב-11.0 גרסאות של Safari ייטענו מראש מגוון סרטונים. מגרסה 11.2, רק המטא-נתונים של הסרטון נטענים מראש. ב-Safari ב-iOS, סרטונים אף פעם לא נטענים מראש.
  • כשמצב חוסך הנתונים (Data Saver) מופעל, ברירת המחדל של preload היא none.

מכיוון שהתנהגויות ברירת המחדל של הדפדפן ביחס ל-preload לא מוגדרות באופן טבעי, סביר להניח שהדבר יהיה הכי מפורש. במקרים שבהם המשתמש יוזם הפעלה, השימוש ב-preload="none" הוא הדרך הקלה ביותר לדחות את טעינת הסרטון בכל הפלטפורמות. המאפיין preload הוא לא הדרך היחידה לדחות את הטעינה של תוכן וידאו. הפעלה מהירה עם טעינה מראש של סרטונים יכולה לתת לכם כמה רעיונות ותובנות לגבי העבודה עם הפעלת סרטונים ב-JavaScript.

למרבה הצער, השימוש בווידאו במקום קובצי GIF מונפשים מתואר בהמשך.

לסרטון שמשמש כתחליף לקובץ GIF מונפש

קובצי GIF מונפשים נהנים משימוש נרחב, אבל הם דומים לסוגים שונים של וידאו, במיוחד בגודל הקובץ. קובצי GIF מונפשים יכולים להצטבר בטווח של כמה מגה-בייט של נתונים. סרטונים באיכות ויזואלית דומה הם בדרך כלל קטנים יותר.

שימוש ברכיב <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>

המאפיינים autoplay, muted ו-loop לא מובן מאליו. יש צורך ב-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, שמאפשר לציין placeholder שייכנס לשטח של הרכיב <video> עד שהסרטון ייטען באופן מדורג. כמו בדוגמאות של <img> לטעינה מדורגת, צריך להסתיר את כתובת ה-URL של הסרטון במאפיין data-src בכל רכיב <source>. משם, צריך להשתמש בקוד JavaScript שדומה לדוגמאות לטעינה מדורגת של תמונות שמבוססות על 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. לאחר מכן, צריך להפעיל את טעינת הסרטון על ידי קריאה ל-method של load של הרכיב, ולאחר מכן המדיה תתחיל לפעול באופן אוטומטי בהתאם למאפיין autoplay.

באמצעות השיטה הזו יש לכם פתרון וידאו שמחקה התנהגות GIF מונפשת, אבל הוא לא צורך את אותו שימוש אינטנסיבי בנתונים כמו קובצי GIF מונפשים, ואתם יכולים לטעון את התוכן בהדרגה.

ספריות בטעינה מדורגת

הספריות הבאות יכולות לעזור לכם לבצע טעינה מדורגת של סרטונים:

  • vanilla-lazyload ו-lozad.js הן אפשרויות קלות במיוחד שמשתמשות רק ב-Intersection Observer. לכן, יש להם ביצועים גבוהים, אבל יהיה צורך למלא אותם בפוליגונים כדי להשתמש בהם בדפדפנים ישנים יותר.
  • yall.js הוא ספרייה שמשתמשת ב-Intersection Observer ועוברת חזרה לגורמים שמטפלים באירועים. אפשר גם לטעון תמונות של סרטון poster באופן הדרגתי באמצעות המאפיין data-poster.
  • אם אתם צריכים ספרייה של טעינה מדורגת ספציפית ל-React, כדאי לשקול react-lazyload. אי אפשר להשתמש ב-Intersection Observer, אבל יש בו שיטה מוכרת לטעינה מדורגת של תמונות בשביל אנשים שרגילים לפתח אפליקציות באמצעות React.

כל אחת מספריות הטעינה העצמית האלה מתועדות היטב, עם הרבה תבניות עיצוב שמתאימות לתהליכים השונים של טעינה מדורגת.