טעינה מראש של תמונות רספונסיביות

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

סקירה כללית על תמונות רספונסיביות

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

  • Chrome: 73.
  • Edge:‏ 79.
  • Firefox:‏ 78.
  • Safari: 17.2.

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

תמונות רספונסיביות מאפשרות לדפדפנים לאחזר משאבי תמונות שונים למכשירים שונים. אם לא משתמשים ב-image CDN, צריך לשמור כמה מימדים לכל תמונה ולציין אותם במאפיין srcset. הערך w מציין לדפדפן את הרוחב של כל גרסה, כדי שהוא יוכל לבחור את הגרסה המתאימה לכל מכשיר:

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

סקירה כללית של טעינה מראש

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

  • Chrome: 50.
  • Edge:‏ ≤79.
  • Firefox: 85.
  • Safari: 11.1.

מקור

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

<link rel="preload" as="image" href="important.png">

imagesrcset וגם imagesizes

הרכיב <link> משתמש במאפיינים imagesrcset ו-imagesizes כדי לטעון מראש תמונות רספונסיביות. צריך להשתמש בהם לצד <link rel="preload">, עם התחביר srcset ו-sizes שנמצא ברכיב <img>.

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

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

כדי לעשות זאת, מוסיפים את הקוד הבא ל-<head> של ה-HTML:

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">

הפעולה הזו מפעילה בקשה לפי אותה לוגיקה לבחירת משאבים שבה נעשה שימוש ב-srcset וב-sizes.

תרחישים לדוגמה

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

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

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

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

  1. פותחים את ההדגמה של המצגת בכרטיסייה חדשה.
  2. מקישים על Control+Shift+J (או על Command+Option+J ב-Mac) כדי לפתוח את כלי הפיתוח.
  3. לוחצים על הכרטיסייה רשתות.
  4. ברשימה הנפתחת Throttling, בוחרים באפשרות Fast 3G.
  5. משביתים את התיבה Disable cache.
  6. לטעון מחדש את הדף.
חלונית הרשת של כלי הפיתוח ל-Chrome, שבה מוצג תרשים מפל מים עם משאב JPEG שמתחיל להוריד רק אחרי קצת JavaScript.
בלי טעינת נתונים מראש, התמונות מתחילות להיטען אחרי שהדפדפן מסיים להריץ את הסקריפט. בתמונה הראשונה, העיכוב הזה לא נחוץ.

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

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

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

טעינת תמונות רקע מראש באמצעות image-set

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

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

הבעיה בתמונות רקע ב-CSS היא שהדפדפן מגלה אותן רק אחרי שהוא מוריד ומעבד את כל קובצי ה-CSS ב-<head> של הדף.

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

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

טעינה מראש של תמונות רספונסיביות מאפשרת לטעון את התמונות האלה מהר יותר.

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x">

השמטת המאפיין href מאפשרת לוודא שדפדפנים שלא תומכים ב-imagesrcset ברכיב <link>, אבל כן תומכים ב-image-set ב-CSS, יורידו את המקור הנכון. עם זאת, הם לא ייהנו מהטעינה מראש במקרה כזה.

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

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

ההשפעות המעשיות של טעינת תמונות רספונסיביות מראש

טעינה מראש של תמונות רספונסיביות יכולה לזרז אותן באופן תיאורטי, אבל מה היא עושה בפועל?

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

התוצאות הבאות התקבלו עבור ללא טעינה מראש ועבור טעינה מראש של תמונות:

  • האפשרות Start Render (התחלת העיבוד) לא השתנתה.
  • המדד Speed Index השתפר מעט (273 אלפיות השנייה, כי התמונות מגיעות מהר יותר ולא תופסות חלק גדול משטח הפיקסלים).
  • Last Painted Hero השתפר באופן משמעותי, ב-1.2 שניות.
השוואה של פס ההמלצות ב-WebPageTest שמראה שתמונות שהועלו מראש מוצגות מהר יותר בכ-1.5 שניות.
התמונות מגיעות מהר יותר משמעותית כשטוענים אותן מראש, וכך משפרות משמעותית את חוויית המשתמש.

טעינה מראש ו-<picture>

קבוצת העבודה בנושא ביצועי האתר דנה בהוספת רכיב מקביל לטעינה מראש עבור srcset ו-sizes, אבל לא עבור הרכיב <picture>, שמטפל בתרחיש לדוגמה של 'הכוונה האומנותית'.

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

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

הלוגיקה של בחירת מקור התמונה של האלמנט <picture> עוברת על המאפיינים media של האלמנטים <source> לפי הסדר, מוצאת את המאפיין הראשון שתואם ומשתמשת במשאב המצורף.

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

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">

טעינה מראש ו-type

הרכיב <picture> תומך גם בהתאמה ל-type הראשון, כדי לאפשר לכם לספק פורמטים שונים של תמונות, כך שהדפדפן יוכל לבחור את פורמט התמונה הראשון שהוא תומך בו. תרחיש לדוגמה זה לא נתמך בחיבור מראש.

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

ההשפעות על Largest Contentful Paint (LCP)

תמונות יכולות להיות מועמדות ל-Largest Contentful Paint‏ (LCP), ולכן טעינה מראש שלהן יכולה לשפר את המדד LCP באתר.

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