טעינה מדורגת של תמונות ורכיבי <iframe>

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

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

כשמדובר ברכיבי <iframe>, אפשר לשפר את האינטראקציה עם רכיב הצבע הבא (INP) של דף במהלך ההפעלה על ידי טעינה מדורגת שלהם. הסיבה לכך היא ש-<iframe> הוא מסמך HTML נפרד לחלוטין עם משאבי משנה משלו. אפשר להריץ רכיבי <iframe> בתהליך נפרד, אבל לא נדיר שהם ישתפו תהליך עם שרשורים אחרים, שעשויים ליצור תנאים שבהם הדפים פחות מגיבים לקלט של משתמשים.

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

תמונות בטעינה מדורגת עם המאפיין loading

ניתן להוסיף את המאפיין loading לרכיבי <img> כדי להנחות את הדפדפנים איך לטעון אותם:

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

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

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

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

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

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

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

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

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

טעינה מדורגת של רכיבי <iframe>

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

הטמעות של צדדים שלישיים הן תרחיש נפוץ לרכיבי <iframe>. לדוגמה, נגני וידאו מוטמעים או פוסטים ברשתות חברתיות בדרך כלל משתמשים ברכיבים של <iframe>, ולרוב הם דורשים מספר משמעותי של משאבי משנה, שגם הם עלולים ליצור תחרות על רוחב הפס ביחס למשאבים ברמה העליונה של הדף. לדוגמה, טעינה מדורגת של הטמעה של סרטון ב-YouTube חוסכת יותר מ-500KiB במהלך טעינת הדף הראשונית, בעוד שפלאגין של לחצן לייק ב-Facebook חוסכת יותר מ-200KiB, רובם JavaScript.

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

המאפיין loading לרכיבי <iframe>

המאפיין loading ברכיבי <iframe> נתמך גם בכל הדפדפנים הראשיים. הערכים של המאפיין loading וההתנהגות שלהם זהים לערכי המאפיין <img> שמשתמשים במאפיין loading:

  • "eager" הוא ערך ברירת המחדל. היא מנחה את הדפדפן לטעון את ה-HTML של רכיב ה-<iframe> ואת משאבי המשנה שלו באופן מיידי.
  • "lazy" דוחה את טעינת ה-HTML של האלמנט <iframe> ומשאבי המשנה שלו עד שהוא נמצא במרחק מוגדר מראש מאזור התצוגה.

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

חזית הבניין

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

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

זאת הזדמנות מצוינת להציג תמונה סטטית שדומה מבחינה חזותית להטמעת הסרטון ולחסוך רוחב פס משמעותי. אחרי שהמשתמש לוחץ על התמונה, היא מוחלפת בהטמעה בפועל <iframe>, שמפעילה את ה-HTML ומשאבי המשנה של רכיב <iframe> של הצד השלישי כדי להתחיל בהורדה.

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

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

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

למרות שבהחלט ניתן ליצור חזיתות משלכם, יש אפשרויות של קוד פתוח שזמינות לצדדים שלישיים פופולריים יותר, כמו למשל lite-youtube-embed לסרטוני YouTube, lite-vimeo-embed לסרטוני Vimeo, ו-React Live Chat Loader לווידג'טים של צ'אטים.

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

במקרה שאתם צריכים לבצע טעינה מדורגת של רכיבי <video>, של אלמנט <video> poster, של תמונות שנטענו על ידי נכס ה-CSS background-image או על ידי אלמנטים לא נתמכים אחרים, אפשר לעשות זאת באמצעות פתרון טעינה מדורגת שמבוסס על JavaScript, כמו lazysizes או yall.js, כי הטעינה המושהית של סוגי המשאבים האלה היא לא תכונה ברמת הדפדפן.

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

רוב הספריות האלה פועלות באמצעות Intersection Overer API — ובנוסף באמצעות Mutation Writeer API אם קוד ה-HTML של הדף משתנה לאחר הטעינה הראשונית — כדי לזהות מתי רכיב נכנס לאזור התצוגה של המשתמש. אם התמונה גלויה או מתקרבת לאזור התצוגה, ספריית ה-JavaScript מחליפה את המאפיין הלא סטנדרטי (בדרך כלל data-src או מאפיין דומה) במאפיין הנכון, כמו src.

נניח שיש לכם סרטון שמחליף קובץ GIF מונפש, אבל אתם רוצים לטעון אותו באופן עצל באמצעות פתרון JavaScript. זה אפשרי באמצעות yall.js עם דפוס הסימון הבא:

<!-- The autoplay, loop, muted, and playsinline attributes are to
     ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
  <source data-src="video.webm" type="video/webm">
  <source data-src="video.mp4" type="video/mp4">
</video>

כברירת מחדל, yall.js שומר על כל רכיבי ה-HTML המתאימים עם סיווג של "lazy". אחרי שטוענים את yall.js ומופעל בדף, הסרטון לא נטען עד שהמשתמש גולל אותו לאזור התצוגה. בשלב הזה, המאפיינים data-src ברכיבי הצאצא <source> של הרכיב <video> מוחלפים במאפייני src, ובעקבות זאת נשלחת בקשה להורדת הסרטון והפעלתו באופן אוטומטי.

בוחנים את הידע

מהו ערך ברירת המחדל של המאפיין loading עבור הרכיבים <img> ו-<iframe>?

"eager"
נכון!
"lazy"
אפשר לנסות שוב.

מתי סביר להשתמש בפתרונות טעינה מושהית המבוססים על JavaScript?

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

מתי חזית היא טכניקה שימושית?

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

השלב הבא: שליפה מראש ועיבוד מראש

עכשיו, אחרי שכבר טיפלתם בטעינה מושהית של תמונות ורכיבי <iframe>, אתם נמצאים בעמדה טובה להבטיח שהדפים ייטענו מהר יותר ויענו על הצרכים של המשתמשים. עם זאת, במקרים מסוימים יכול להיות שהטעינה ספקולטיבית של משאבים תהיה רצויה. במודול הבא, נלמד על שליפה מראש (prefetch) ועיבוד מראש, ואיך השימוש בשיטות האלה (אם משתמשים בהן בזהירות) יכול לזרז משמעותית את הניווט לדפים הבאים, כי הם נטענים מראש.