ביצועי תמונה

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

אפשר להוסיף תמונות לדף באמצעות האלמנטים <img> או <picture>, או באמצעות המאפיין background-image ב-CSS.

Image size

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

עם זאת, יש הרבה משתנים שמשפיעים על בחירת הגודל המתאים של התמונה, ולכן בחירת הגודל המתאים של התמונה בכל מקרה היא משימה די מורכבת. בשנת 2010, כשהושק אייפון 4, רזולוציית המסך (640x960) הייתה כפולה מזו של אייפון 3 (320x480). עם זאת, הגודל הפיזי של המסך של iPhone 4 נשאר בערך כמו של iPhone 3.

אם הייתי מציג הכול ברזולוציה הגבוהה יותר, הטקסט והתמונות היו קטנים משמעותית – חצי מהגודל הקודם שלהם, ליתר דיוק. במקום זאת, פיקסל אחד הפך ל-2 פיקסלים של המכשיר. היחס הזה נקרא יחס הפיקסלים של המכשיר (DPR). ב-iPhone 4 (ובדגמי אייפון רבים שיצאו אחריו) יחס ה-DPR היה 2.

נחזור לדוגמה הקודמת. אם למכשיר יש DPR של 2 והתמונה מוצגת במאגר בגודל 500 פיקסלים על 500 פיקסלים, אז הגודל האופטימלי הוא עכשיו תמונה ריבועית בגודל 1, 000 פיקסלים (שנקרא גודל פנימי). באופן דומה, אם ערך ה-DPR של המכשיר הוא 3, הגודל האופטימלי של תמונה ריבועית יהיה 1,500 פיקסלים.

srcset

הרכיב <img> תומך במאפיין srcset, שמאפשר לציין רשימה של מקורות תמונות אפשריים שהדפדפן יכול להשתמש בהם. כל מקור תמונה שצוין צריך לכלול את כתובת ה-URL של התמונה, ומתאר של רוחב או צפיפות פיקסלים.

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>

בקטע הקוד הקודם של HTML נעשה שימוש בתיאור צפיפות הפיקסלים כדי להציע לדפדפן להשתמש ב-image-500.png במכשירים עם DPR של 1, ב-image-1000.jpg במכשירים עם DPR של 2 וב-image-1500.jpg במכשירים עם DPR של 3.

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

sizes

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

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

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
  sizes="(min-width: 768px) 500px, 100vw"
>

בקטע ה-HTML הקודם, המאפיין srcset מציין רשימה של תמונות פוטנציאליות שהדפדפן יכול לבחור מתוכן, מופרדות בפסיקים. כל מועמד ברשימה מורכב מכתובת ה-URL של התמונה, ואחריה תחביר שמציין את הרוחב המקורי של התמונה. הגודל המקורי של תמונה הוא המידות שלה. לדוגמה, תיאור של 1000w מציין שהרוחב הפנימי של התמונה הוא 1,000 פיקסלים.

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

לאחר מכן הדפדפן יכול לשלב את המידע הזה עם רשימת srcsetמקורות התמונות כדי למצוא את התמונה האופטימלית. לדוגמה, אם המשתמש נמצא במכשיר נייד עם רוחב מסך של 320 פיקסלים ו-DPR של 3, התמונה מוצגת ברוחב של 320 CSS pixels x 3 DPR = 960 device pixels. בדוגמה הזו, התמונה בגודל הכי קרוב היא image-1000.jpg, שהרוחב שלה הוא 1,000 פיקסלים (1000w).

פורמטים של קבצים

דפדפנים תומכים בכמה פורמטים שונים של קובצי תמונות. פורמטים מודרניים של תמונות כמו WebP ו-AVIF עשויים לספק דחיסה טובה יותר מאשר PNG או JPEG, כך שגודל קובץ התמונה יהיה קטן יותר וזמן ההורדה יהיה קצר יותר. הצגת תמונות בפורמטים מודרניים מאפשרת לקצר את זמן הטעינה של משאב, וכתוצאה מכך עשויה להקטין את הערך של Largest Contentful Paint ‏ (LCP).

‫WebP הוא פורמט שנתמך באופן נרחב ופועל בכל הדפדפנים המודרניים. לרוב, פורמט WebP מספק דחיסה טובה יותר מאשר JPEG, ‏ PNG או GIF, והוא מציע גם דחיסה עם אובדן נתונים וגם דחיסה ללא אובדן נתונים. פורמט WebP תומך גם בשקיפות של ערוץ אלפא, גם כשמשתמשים בדחיסת נתונים מסוג lossy – תכונה שקודק JPEG לא מציע.

‫AVIF הוא פורמט תמונה חדש יותר, ולמרות שהוא לא נתמך באופן נרחב כמו WebP, יש לו תמיכה סבירה בדפדפנים. פורמט AVIF תומך בדחיסה עם אובדן נתונים וגם בדחיסה ללא אובדן נתונים, ובבדיקות נמצא שבמקרים מסוימים הוא חוסך יותר מ-50% בהשוואה ל-JPEG. בנוסף, AVIF מציע תכונות של טווח צבעים רחב (WCG) וטווח דינמי גבוה (HDR).

דחיסה

כשמדובר בתמונות, יש שני סוגים של דחיסה:

  1. דחיסה עם אובדן נתונים
  2. דחיסה ללא אובדן נתונים

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

דחיסה ללא אובדן נתונים מקטינה את גודל הקובץ על ידי דחיסת תמונה ללא אובדן נתונים. דחיסה ללא אובדן נתונים מתארת פיקסל על סמך ההבדל בינו לבין הפיקסלים השכנים שלו. דחיסת נתונים מסוג lossless משמשת לפורמטים של התמונות הבאים: GIF,‏ PNG,‏ WebP ו-AVIF.

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

הרכיב <picture>

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

<picture>
  <source type="image/avif" srcset="image.avif">
  <source type="image/webp" srcset="image.webp">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image.jpg">
</picture>

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

אלמנט <picture> צריך להכיל אלמנט <img>. המאפיינים alt, width ו-height מוגדרים ב-<img> ומשמשים ללא קשר ל-<source> שנבחר.

הרכיב <source> תומך גם במאפיינים media, srcset ו-sizes. בדומה לדוגמה <img> שצוינה קודם, התגים האלה מציינים לדפדפן איזו תמונה לבחור באזורי תצוגה שונים.

<picture>
  <source
    media="(min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg">
</picture>

המאפיין media מקבל תנאי מדיה. בדוגמה הקודמת, ה-DPR של המכשיר משמש כתנאי המדיה. בכל מכשיר עם DPR גדול מ-1.5 או שווה לו, נעשה שימוש ברכיב <source> הראשון. האלמנט <source> אומר לדפדפן שבמכשירים עם אזור תצוגה ברוחב של יותר מ-768 פיקסלים, התמונה שנבחרה תוצג ברוחב של 500 פיקסלים. במכשירים קטנים יותר, הרוחב של אזור התצוגה תופס את כל הרוחב. אם משלבים את המאפיינים media ו-srcset אפשר לשלוט בצורה מדויקת יותר בתמונה שבה רוצים להשתמש.

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

רוחב אזור התצוגה (פיקסלים) ‫1 DPR ‫1.5 DPR ‫2 DPR ‫3 DPR
320 500.jpg 500.jpg 500.jpg 1000.jpg
480 500.jpg 500.jpg 1000.jpg 1500.jpg
560 500.jpg 1000.jpg 1000.jpg 1500.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

מכשירים עם DPR של 1 מורידים את התמונה image-500.jpg, כולל רוב המשתמשים במחשבים – שרואים את התמונה בגודל חיצוני של 500 פיקסלים ברוחב. לעומת זאת, משתמשים בנייד עם DPR של 3 מורידים תמונה גדולה יותר image-1500.jpg – אותה תמונה שמשמשת במחשבים עם DPR של 3.

<picture>
  <source
    media="(min-width: 561px) and (min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw">
  <source
    media="(max-width: 560px) and (min-resolution: 1.5x)"
    srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg">
</picture>

בדוגמה הזו, האלמנט <picture> מותאם כך שיכלול אלמנט נוסף <source> כדי להשתמש בתמונות שונות במכשירים רחבים עם DPR גבוה:

רוחב אזור התצוגה (פיקסלים) ‫1 DPR ‫1.5 DPR ‫2 DPR ‫3 DPR
320 500.jpg 500.jpg 1000-sm.jpg 1000-sm.jpg
480 500.jpg 500.jpg 1000-sm.jpg 1500-sm.jpg
560 500.jpg 1000-sm.jpg 1000-sm.jpg 1500-sm.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

בעזרת השאילתה הנוספת הזו, אפשר לראות ש-image-1000-sm.jpg ו-image-1500-sm.jpg מוצגים באזורי תצוגה קטנים. המידע הנוסף הזה מאפשר לכם לדחוס את התמונות עוד יותר, כי קשה לראות את האפקטים של הדחיסה בגודל ובצפיפות האלה, וגם לא נפגעת איכות התמונה במחשבים.

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

<picture>
  <source
    media="(min-width: 561px)"
    srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x">
  <source
    media="(max-width: 560px)"
    srcset="/image-500.jpg 1x, /image-1000.jpg 2x">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg">
</picture>

בקטע ה-HTML הקודם, תיאורי הרוחב הוסרו לטובת תיאורי יחס הפיקסלים של המכשיר. התמונות שמוצגות במכשיר נייד מוגבלות ל-/image-500.jpg או ל-/image-1000.jpg, גם במכשירים עם DPR של 3.

ניהול מורכבות

כשעובדים עם תמונות רספונסיביות, יכול להיות שיהיו לכם הרבה וריאציות של גדלים ופורמטים לכל תמונה. בדוגמה הקודמת, נעשה שימוש בווריאציות של כל גודל, אבל לא נעשה שימוש ב-AVIF וב-WebP. כמה וריאציות צריך ליצור? כמו בהרבה בעיות הנדסיות, התשובה היא בדרך כלל "זה תלוי".

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

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

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

הצגת תמונות על סמך כותרת הבקשה Accept

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

if (request.headers.accept) {
  if (request.headers.accept.includes('image/avif')) {
    return reply.from('image.avif');
  } else if (request.headers.accept.includes('image/webp')) {
    return reply.from('image.webp');
  }
}

return reply.from('image.jpg');

קטע ה-HTML שמוצג למעלה הוא גרסה פשוטה של הקוד שאפשר להוסיף לקצה העורפי של JavaScript בשרת כדי לבחור את פורמט התמונה האופטימלי ולהציג אותו. אם הכותרת Accept של הבקשה כוללת image/avif, התמונה בפורמט AVIF מוצגת. אחרת, אם הכותרת Accept כוללת את הערך image/webp, התמונה בפורמט WebP תוצג. אם אף אחד מהתנאים האלה לא מתקיים, התמונה בפורמט JPEG תוצג.

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

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

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

טעינה מדורגת

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

מאפיין פענוח

המאפיין decoding מציין לדפדפן איך לפענח את התמונה. יש שלושה ערכים אפשריים:

  • async אומר לדפדפן שאפשר לפענח את התמונה באופן אסינכרוני, מה שעשוי לשפר את הזמן עד לרינדור של תוכן אחר.
  • sync מציין לדפדפן שהתמונה תוצג בו-זמנית עם תוכן אחר.
  • auto (ברירת מחדל) מאפשרת לדפדפן להחליט מה הכי טוב למשתמש.

אפשר להשתמש בשיטה decode במופע של HTMLImageElement ב-JavaScript, כשמוסיפים תמונה ל-DOM.

הדגמת תמונה

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

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

‫GIF.
תשובה נכונה!
JPEG.
אפשר לנסות שוב.
PNG.
תשובה נכונה!
WebP.
תשובה נכונה!
AVIF.
תשובה נכונה!

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

‫GIF.
אפשר לנסות שוב. למרות שפורמט GIF תומך רק בפלטה מוגבלת של 256 צבעים, צריך לבצע את הקידוד עם אובדן נתונים לפני ההמרה ל-GIF.
JPEG.
תשובה נכונה!
PNG.
אפשר לנסות שוב.
WebP.
תשובה נכונה!
AVIF.
תשובה נכונה!

מה מתאר הרוחב (לדוגמה, 1000w) אומר לדפדפן על תמונה מועמדת שצוינה במאפיין srcset?

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

מה המאפיין sizes אומר לדפדפן על רכיב <img> שהוא מוחל עליו?

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

הבא בתור: ביצועי הסרטון

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