טעינה מדורגת של תמונות ברמת הדפדפן לאינטרנט

תמיכה בדפדפנים

  • Chrome: 77.
  • Edge: ‏ 79.
  • Firefox: ‏ 75.
  • Safari: 15.4.

אפשר להשתמש במאפיין loading כדי לטעון תמונות באיטרציה (lazy-load) בלי צורך לכתוב קוד מותאם אישית לטעינה באיטרציה או להשתמש בספריית JavaScript נפרדת. דמו של התכונה:

תמונות שמופעלת בהן טעינה מדורגת נטענות כשהמשתמש גולל בדף.

בדף הזה מוסבר בפירוט איך מטמיעים טעינת פריטים בזמן אמת בדפדפן.

למה כדאי להשתמש טעינה איטית ברמת הדפדפן?

לפי HTTP Archive, תמונות הן סוג הנכס הכי פופולרי ברוב האתרים, ובדרך כלל הן תופסות יותר ברוחב פס מכל משאב אחר. ב-90% מהאתרים נשלחות יותר מ-5MB של תמונות במחשבים ובניידים.

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

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

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

המאפיין loading

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

אפשר להשתמש במאפיין loading כדי לדחות לחלוטין את הטעינה של תמונות מחוץ למסך:

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

אלה הערכים הנתמכים של המאפיין loading:

  • lazy: דחיית טעינת המשאב עד שהוא מגיע למרחק מחושב מחלון התצוגה.
  • eager: ברירת המחדל של התנהגות הטעינה בדפדפן, זהה לאי-הכללת המאפיין, כלומר התמונה נטענת ללא קשר למיקום שלה בדף. זהו ערך ברירת המחדל, אבל כדאי להגדיר אותו באופן מפורש אם הכלים שלכם מוסיפים את הערך loading="lazy" באופן אוטומטי כשאין ערך מפורש, או אם ה-linter מתריע אם הערך לא מוגדר באופן מפורש.

הקשר בין המאפיין loading לבין תעדוף האחזור

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

אם רוצים להגדיל את העדיפות של אחזור תמונה חשובה (לדוגמה, התמונה מסוג LCP), משתמשים ב-Fetch Priority עם fetchpriority="high".

טעינת תמונה עם loading="lazy" ו-fetchpriority="high" עדיין מתעכבת כשהיא מחוץ למסך, ולאחר מכן היא מאוחזרת בעדיפות גבוהה כשהיא כמעט בתוך אזור התצוגה. השילוב הזה לא ממש הכרחי, כי סביר להניח שהדפדפן יטמיע את התמונה הזו בעדיפות גבוהה בכל מקרה.

ערכי סף של מרחק מאזור התצוגה

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

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

ערך הסף של המרחק משתנה בהתאם לגורמים הבאים:

ערכי ברירת המחדל של סוגי החיבורים היעילים השונים מופיעים במקור Chromium. כדי להתנסות בערכי הסף השונים האלה, אפשר להגביל את קצב הנתונים ברשת ב-DevTools.

שיפורים בחסכון בנתונים ובסף המרחק מחלון התצוגה

ביולי 2020 ביצענו שיפורים משמעותיים ב-Chrome כדי להתאים את ערכי הסף של מרחק התמונה מחלון התצוגה (viewport) לטעינת פריטים בזמן אמת, כדי לעמוד בציפיות של המפתחים.

בחיבורים מהירים (4G), הפחתנו את ערכי הסף של Chrome למרחק ממרחב התצוגה מ-3000px ל-1250px. בחיבורים איטיים יותר (3G ומטה), שינינו את ערך הסף מ-4000px ל-2500px. השינוי הזה מאפשר להשיג שתי מטרות:

  • <img loading=lazy> מתנהגת בצורה דומה יותר לחוויה שמציעות ספריות של טעינת JavaScript בזמן אמת.
  • ערכי הסף החדשים של המרחק מחלון התצוגה עדיין משמעותם שהתמונות יוכלו להיטען עד שהמשתמש יגלול אליהן.

בהמשך מוצגת השוואה בין ערכי הסף הישנים לערכי הסף החדשים של המרחק מחלון התצוגה באחד מהדמואים שלנו בחיבור מהיר (4G):

ערכי הסף החדשים והמשופרים של טעינת תמונות באיטרציה, שבהם הורידו את ערכי הסף של המרחק מחלון התצוגה לחיבורים מהירים מ-3,000 פיקסלים ל-1,250 פיקסלים.
השוואה בין הספים הקודמים לבין הספים החדשים ששימשו לטעינה איטית ברמת הדפדפן.

ואלה הסף החדש לעומת LazySizes (ספריית JavaScript פופולרית לטעינת פריטים בזמן אמת):

ערכי הסף החדשים של המרחק מחלון התצוגה ב-Chrome, שבו נטענות תמונות בנפח 90KB, בהשוואה לטעינה של LazySizes בנפח 70KB, באותו מצב רשת.
השוואה בין ערכי הסף לטעינה איטית ב-Chrome וב-LazySizes.

הוספת מאפייני מאפיינים לתמונות

בזמן שהדפדפן טוען תמונה, הוא לא יודע מיד את המימדים שלה, אלא אם הם צוינו במפורש. כדי לאפשר לדפדפן להקצות מספיק מקום בדף לתמונות, וכדי להימנע משינויים מפריעים בפריסה, מומלץ להוסיף את המאפיינים width ו-height לכל תגי <img>.

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

לחלופין, אפשר לציין את הערכים שלהם ישירות בסגנון inline:

<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">

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

טעינת ה-Lazy ב-Chromium מיושמת באופן שמגדיל את הסיכוי שהתמונות ייטענו ברגע שהן גלויות, אבל עדיין יש סיכוי שהן לא ייטענו בזמן הנכון. במקרה כזה, אי ציון הערכים width ו-height בתמונות מגביר את ההשפעה שלהן על שינוי הפריסה המצטבר. אם אי אפשר לציין את המימדים של התמונות, טעינת ה-lazy שלהן יכולה לחסוך משאבי רשת, אבל כתוצאה מכך יהיו יותר שינויי פריסה.

ברוב התרחישים, תמונות עדיין נטענות באיטרציה אם לא מציינים את המימדים, אבל יש כמה מקרים קיצוניים שחשוב לדעת עליהם. אם לא מציינים את הערכים של width ו-height, ברירת המחדל של מידות התמונה היא 0x0 פיקסלים. אם יש לכם גלריה של תמונות, יכול להיות שהדפדפן יחליט שכל התמונות ייכנסו למסך כבר בהתחלה, כי כל תמונה לא תופסת מקום ואף תמונה לא מוסטת מחוץ למסך. במקרה כזה, הדפדפן מחליט לטעון את הכל, וכתוצאה מכך הדף נטען לאט יותר.

דוגמה לאופן שבו loading פועל עם מספר גדול של תמונות מופיעה בדמו הזה.

אפשר גם לטעון ב-lazy תמונות שהגדרתם באמצעות הרכיב <picture>:

<picture>
  <source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
  <img src="photo.jpg" loading="lazy">
</picture>

הדפדפן מחליט איזו תמונה לטעון מכל אחד מהאלמנטים <source>, אבל צריך להוסיף את loading רק לאלמנט החלופי <img>.

תמיד צריך לטעון מראש תמונות שגלומות באזור התצוגה הראשון

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

יש להשתמש ב-loading=lazy רק לתמונות שמחוץ לאזור התצוגה הראשוני. הדפדפן לא יכול לטעון תמונה באופן איטי עד שהוא יודע איפה התמונה אמורה להיות בדף, ולכן הן נטענות לאט יותר.

<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">

<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">

ירידה הדרגתית ביכולת הפעולה

דפדפנים שלא תומכים במאפיין loading מתעלמים ממנו. הם לא נהנים מהיתרונות של טעינת פריטים בזמן הצורך, אבל אין השפעה שלילית על ההכללה שלהם.

שאלות נפוצות

ריכזנו כאן כמה שאלות נפוצות בנושא טעינת פריטים בזמן אמת ברמת הדפדפן.

האם אפשר לטעון תמונות באופן אוטומטי ב-Chrome?

בעבר, Chromium ביצע באופן אוטומטי טעינה איטית של תמונות שמתאימות לדחייה אם מצב טעינה מהירה הופעל ב-Chrome ל-Android, והמאפיין loading לא סופק או שהוגדר ל-loading="auto". עם זאת, מצב Lite ו-loading="auto" הוצאו משימוש ואין תוכניות לספק טעינת פריטים בזמן אמת (lazy-load) של תמונות ב-Chrome.

האם אפשר לשנות את המרחק של התמונה מחלון התצוגה לפני שהיא נטענת?

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

האם אפשר להשתמש במאפיין loading בתמונות רקע ב-CSS?

לא, אפשר להשתמש בו רק עם תגי <img>.

שימוש ב-loading="lazy" יכול למנוע טעינת תמונות כשהן לא גלויות אבל נמצאות במרחק המחושב. יכול להיות שהתמונות האלה יופיעו מאחורי קרוסלה או יהיו מוסתרות באמצעות CSS בגדלי מסך מסוימים. לדוגמה, דפדפני Chrome,‏ Safari ו-Firefox לא טוענים תמונות באמצעות עיצוב display: none;, לא ברכיב התמונה ולא ברכיב האב. עם זאת, שיטות אחרות להסתרת תמונות, כמו שימוש בסגנון opacity:0, עדיין גורמות לדפדפן לטעון את התמונה. תמיד חשוב לבדוק היטב את ההטמעה כדי לוודא שהיא פועלת כמצופה.

בגרסה 121 של Chrome השתנו ההתנהגות של תמונות עם גלילה אופקית, כמו קרוסלות. עכשיו נעשה בהם שימוש באותם ערכי סף כמו בגלילה אנכית. כלומר, בתרחיש לדוגמה של קרוסלה, התמונות ייטענו לפני שהן יהיו גלויות בחלון התצוגה. המשמעות היא שהסיכוי שהמשתמשים יבחינו בחיוב על טעינה של תמונות נמוך יותר, אבל העלויות של הורדות יהיו גבוהות יותר. אתם יכולים להשתמש בהדגמה של טעינת פריטים ב-Lazy Loading אופקית כדי להשוות בין ההתנהגות ב-Chrome לבין ההתנהגות ב-Safari וב-Firefox.

מה קורה אם כבר משתמשים בספרייה או בסקריפט של צד שלישי כדי לטעון תמונות באיטרציה?

מאחר שיש תמיכה מלאה בטעינה איטית (lazy load) בדפדפנים מודרניים, סביר להניח שאין צורך בספרייה או בתסריט של צד שלישי כדי לטעון תמונות באיטיות.

אחת מהסיבות להמשיך להשתמש בספרייה של צד שלישי לצד loading="lazy" היא לספק polyfill לדפדפנים שלא תומכים במאפיין, או כדי לקבל שליטה רבה יותר על מועד ההפעלה של טעינת הנכסים בזמן אמת.

איך מטפלים בדפדפנים שלא תומכים בטעינה איטית?

טעינת תמונות ב-lazy load ברמת הדפדפן נתמכת היטב בכל הדפדפנים העיקריים, ומומלצת ברוב תרחישי השימוש כדי להסיר את הצורך ביחסי תלות נוספים ב-JavaScript.

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

אפשר להשתמש בנכס loading כדי לזהות אם דפדפן תומך בפיצ'ר:

if ('loading' in HTMLImageElement.prototype) {
  // supported in browser
} else {
  // fetch polyfill/third-party library
}

לדוגמה, lazysizes היא ספרייה פופולרית של JavaScript לטעינה איטית. אפשר לזהות תמיכה במאפיין loading כדי לטעון את lazysizes כספריית חלופית רק כשאין תמיכה ב-loading. כך זה עובד:

  • כדי למנוע טעינה מיידית בדפדפנים שלא תומכים בכך, מחליפים את <img src> ב-<img data-src>. אם יש תמיכה במאפיין loading, מחליפים את data-src ב-src.
  • אם loading לא נתמך, אפשר לטעון חלופה מ-lazysizes ולהפעיל אותה, באמצעות הכיתה lazyload כדי לציין אילו תמונות לטעון באיטרציות:
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">

<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">

<script>
  if ('loading' in HTMLImageElement.prototype) {
    const images = document.querySelectorAll('img[loading="lazy"]');
    images.forEach(img => {
      img.src = img.dataset.src;
    });
  } else {
    // Dynamically import the LazySizes library
    const script = document.createElement('script');
    script.src =
      'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
    document.body.appendChild(script);
  }
</script>

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

האם טעינת פריטים בזמן אמת (lazy loading) של iframes נתמכת גם בדפדפנים?

תמיכה בדפדפנים

  • Chrome: 77.
  • Edge: ‏ 79.
  • Firefox: 121.
  • Safari: 16.4.

גם <iframe loading=lazy> עבר סטנדרטיזציה. כך תוכלו לטעון iframes באופן איטי באמצעות המאפיין loading. מידע נוסף זמין במאמר הגיע הזמן להשתמש בטעינה איטית של iframes מחוץ למסך.

איך טעינה איטית ברמת הדפדפן משפיעה על מודעות בדף אינטרנט?

כל המודעות שמוצגות למשתמש כתמונות או כ-iframe נטענות באיטרציה (lazy load), בדיוק כמו כל תמונה או iframe אחרים.

איך מטפלים בתמונות כשמדפיסים דף אינטרנט?

כל התמונות והפריטים מסוג iframe נטענים מיד כשהדף מודפס. לפרטים נוספים, ראו בעיה מס' 875403.

האם Lighthouse מזהה טעינה איטית ברמת הדפדפן?

בגרסה Lighthouse 6.0 ואילך, המערכת מביאה בחשבון שיטות טעינה איטית של תמונות מחוץ למסך שיכולות להשתמש בתנאי סף שונים, וכך מאפשרת להן לעבור את הביקורת דחיית תמונות מחוץ למסך.

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

תמיכה בדפדפנים בטעינה איטית של תמונות יכולה להקל עליכם מאוד לשפר את הביצועים של הדפים.

האם שמת לב להתנהגות לא רגילה כשהתכונה הזו מופעלת ב-Chrome? דיווח על באג