תמונות הן בדרך כלל המשאב הכבד והנפוץ ביותר באינטרנט. לכן, אופטימיזציה של תמונות יכולה לשפר משמעותית את הביצועים באתר. ברוב המקרים, אופטימיזציה של תמונות פירושה קיצור הזמן שנדרש להעברת הנתונים ברשת על ידי שליחת פחות בייטים. אבל אפשר גם לבצע אופטימיזציה של כמות הבייטים שנשלחת למשתמש על ידי הצגת תמונות בגודל שמתאים למכשיר של המשתמש.
אפשר להוסיף תמונות לדף באמצעות האלמנטים <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, כך שגודל קובץ התמונה יהיה קטן יותר וזמן ההורדה יהיה קצר יותר. הצגת תמונות בפורמטים מודרניים מאפשרת לקצר את זמן הטעינה של משאב, וכתוצאה מכך לקצר את הזמן שנדרש לטעינת רכיב התוכן הכי גדול (LCP).
WebP הוא פורמט שנתמך באופן נרחב ופועל בכל הדפדפנים המודרניים. לרוב, פורמט WebP מספק דחיסה טובה יותר מאשר JPEG, PNG או GIF, והוא מציע גם דחיסה עם אובדן נתונים וגם דחיסה ללא אובדן נתונים. פורמט WebP תומך גם בשקיפות של ערוץ אלפא, גם כשמשתמשים בדחיסה מסוג lossy – תכונה שקודק JPEG לא מציע.
AVIF הוא פורמט תמונה חדש יותר, ולמרות שהוא לא נתמך באופן נרחב כמו WebP, יש לו תמיכה סבירה בדפדפנים. פורמט AVIF תומך בדחיסה עם אובדן נתונים וגם בדחיסה ללא אובדן נתונים, ובבדיקות נמצא שבמקרים מסוימים הוא חוסך יותר מ-50% בהשוואה ל-JPEG. בנוסף, AVIF מציע תכונות של טווח צבעים רחב (WCG) וטווח דינמי גבוה (HDR).
דחיסה
כשמדובר בתמונות, יש שני סוגים של דחיסה:
דחיסה עם אובדן נתונים פועלת על ידי הפחתת הדיוק של התמונה באמצעות קוונטיזציה, וייתכן שפרטי צבע נוספים יימחקו באמצעות דגימת משנה של כרומה. דחיסה עם אובדן נתונים יעילה במיוחד בתמונות בצפיפות גבוהה עם הרבה רעשים וצבעים – בדרך כלל תמונות או צילומים עם תוכן דומה. הסיבה לכך היא שהארטיפקטים שנוצרים כתוצאה מדחיסה עם אובדן נתונים פחות בולטים בתמונות מפורטות כאלה. עם זאת, דחיסה עם אובדן נתונים עשויה להיות פחות יעילה בתמונות שמכילות קצוות חדים, כמו איורים, פרטים בולטים או טקסט. אפשר להשתמש בדחיסה עם אובדן נתונים בתמונות בפורמטים JPEG, WebP ו-AVIF.
דחיסה ללא אובדן נתונים מקטינה את גודל הקובץ על ידי דחיסת תמונה ללא אובדן נתונים. דחיסה ללא אובדן נתונים מתארת פיקסל על סמך ההבדל בינו לבין הפיקסלים השכנים שלו. דחיסה ללא אובדן נתונים משמשת לפורמטים של התמונות 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 אם אף אחד מהפורמטים AVIF או WebP לא נתמך.
אלמנט <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 גדול מ-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
המאפיין decoding
אומר לדפדפן איך לפענח את התמונה. ערך של async
אומר לדפדפן שאפשר לפענח את התמונה באופן אסינכרוני, מה שעשוי לשפר את הזמן שנדרש לעיבוד של תוכן אחר. הערך sync
אומר לדפדפן שהתמונה צריכה להיות מוצגת באותו הזמן עם תוכן אחר.
ערך ברירת המחדל של auto
מאפשר לדפדפן להחליט מה הכי טוב למשתמש.
הדגמות של תמונות
בוחנים את הידע
באילו פורמטים של תמונות יש תמיכה בדחיסה ללא אובדן נתונים?
באילו פורמטים של תמונות יש תמיכה בדחיסה עם אובדן נתונים?
מה מתאר הרוחב (לדוגמה, 1000w
) אומר לדפדפן על תמונה מועמדת שצוינה במאפיין srcset
?
מה המאפיין sizes
אומר לדפדפן על רכיב <img>
שהוא מוחל עליו?
<img>
במאפיין srcset
.
<img>
של srcset
צריך לטעון, בהתחשב בממדים של אזור התצוגה הנוכחי של המשתמש.
הנושא הבא: ביצועי הסרטון
תמונות הן אמנם סוג המדיה הנפוץ ביותר באינטרנט, אבל הן לא הסוג היחיד שצריך להתייחס אליו כשמדובר בביצועים. סרטונים הם סוג נפוץ נוסף של מדיה שנעשה בה שימוש באינטרנט, ויש להם שיקולים משלהם לגבי הביצועים. במודול הבא של הקורס הזה, נסביר על כמה טכניקות לאופטימיזציה של סרטונים ואיך לטעון אותם בצורה יעילה.