תמונות הן בדרך כלל המרכיב שמכיל את רוב הבייטים שהורדתם בדף אינטרנט, וגם תופסות לעיתים קרובות חלק משמעותי משטח התצוגה. כתוצאה מכך, לעיתים קרובות אופטימיזציה של תמונות תפיק חלק מהשיפורים המשמעותיים ביותר בבייטים ובביצועים של האתר: ככל שהדפדפן צריך להוריד פחות בייטים, כך יש פחות תחרות על רוחב הפס של הלקוח, וכך הדפדפן יכול להוריד ולעבד תוכן שימושי במסך מהר יותר.
אופטימיזציה של תמונות היא גם אמנות וגם מדע: אמנות כי אין תשובה אחת ודאית לאופן הטוב ביותר לדחוס תמונה ספציפית, ומדע כי יש הרבה שיטות ואלגוריתמים מפותחים שיכולים לצמצם באופן משמעותי את גודל התמונה. כדי למצוא את ההגדרות האופטימליות לתמונה, צריך לבצע ניתוח יסודי במגוון מאפיינים: יכולות הפורמט, תוכן הנתונים המקודדים, האיכות, ממדי הפיקסלים ועוד.
אופטימיזציה של תמונות וקטוריות
כל הדפדפנים המודרניים תומכים ב-Scalable Vector Graphics (SVG), שהוא פורמט תמונה מבוסס XML לגרפיקה דו-ממדית. אפשר להטמיע את ה-markup של ה-SVG ישירות בדף או כמשאב חיצוני. רוב תוכנות הציור מבוססות-הוקטור יכולות ליצור קובצי SVG, או שאפשר לכתוב אותם ביד ישירות בכלי לעריכת טקסט שאתם אוהבים.
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 612 792" xml:space="preserve">
<g id="XMLID_1_">
<g>
<circle fill="red" stroke="black" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/>
</g>
</g>
</svg>
הדוגמה שלמעלה מעבדת את הצורה הפשוטה של העיגול עם קווי מתאר שחורים ורקע אדום, ויוצאה מ-Adobe Illustrator.
<?xml version="1.0" encoding="utf-8"?>
כפי שניתן לראות, הוא מכיל הרבה מטא-נתונים, כמו פרטי שכבות, תגובות ומרחבי שמות של XML, שבדרך כלל לא נחוצים לצורך עיבוד הנכס בדפדפן. לכן, תמיד כדאי להקטין את קובצי ה-SVG על ידי הרצה באמצעות כלי כמו SVGO.
לדוגמה, SVGO מקטין את הגודל של קובץ ה-SVG שלמעלה שנוצר על ידי Illustrator ב-58%, מ-470 בייט ל-199 בייט.
<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 792"><circle fill="red" stroke="#000" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/></svg>
מכיוון ש-SVG הוא פורמט שמבוסס על XML, אפשר גם להחיל דחיסת GZIP כדי לצמצם את גודל ההעברה שלו. חשוב לוודא שהשרת מוגדר לדחיסת נכסי SVG.
תמונה רסטר היא פשוט רשת דו-מימדית של 'פיקסלים' נפרדים. לדוגמה, תמונה בגודל 100x100 פיקסלים היא רצף של 10,000 פיקסלים. כל פיקסל שומר את ערכי RGBA: ערוץ אדום (R), ערוץ ירוק (G), ערוץ כחול (B) וערוץ אלפא (שקיפות) (B).
באופן פנימי, הדפדפן מקצה 256 ערכים (גוונים) לכל ערוץ, שמתרגמים ל-8 ביט לכל ערוץ (2 ^ 8 = 256) ול-4 בייטים לכל פיקסל (4 ערוצים x 8 ביט = 32 ביט = 4 בייטים). לכן, אם אנחנו יודעים את המימדים של התא, אנחנו יכולים לחשב בקלות את גודל הקובץ:
- תמונה בגודל 100x100 פיקסלים מורכבת מ-10,000 פיקסלים
- 10,000 פיקסלים x 4 בייטים = 40,000 בייטים
- 40,000 בייטים חלקי 1,024 = 39KB
מידות | פיקסלים | גודל הקובץ |
---|---|---|
100 x 100 | 10,000 | 39 KB |
200 x 200 | 40,000 | 156 KB |
300 X 300 | 90,000 | 351 KB |
500 x 500 | 250,000 | 977 KB |
800 x 800 | 640,000 | 2,500KB |
39KB לתמונה בגודל 100x100 פיקסלים אולי לא נראה כמו הרבה, אבל גודל הקובץ גדל במהירות כשמדובר בתמונות גדולות יותר, וההורדה של נכסי תמונה כאלה איטית ויקרה. עד כה הפוסט הזה התמקד רק בפורמט תמונה 'לא דחוס'. למרבה המזל, ניתן לעשות הרבה דברים כדי להקטין את גודל קובץ התמונה.
אסטרטגיה פשוטה אחת היא לצמצם את 'עומק הביטים' של התמונה מ-8 ביט לכל ערוץ לצבעים פחותים בצבעים: 8 ביט לכל ערוץ נותנים לנו 256 ערכים לכל ערוץ ו-16,777,216 (256 ^ 3) צבעים בסך הכול. מה קורה אם מצמצמים את לוח הצבעים ל-256 צבעים? כך תצטרכו רק 8 ביט בסך הכול לערוצי ה-RGB, ותחסכו מיד שני בייטים לכל פיקסל – חיסכון של 50% ביחס לפורמט המקורי של 4 בייטים לכל פיקסל!
בסצנות מורכבות עם מעברי צבעים הדרגתיים (למשל: הדרגתיות או שמיים), צריך להשתמש בלוחות צבעים גדולים יותר כדי להימנע מפריטים חזותיים כמו שמיים מפוקסלים בנכס 5 ביט. מצד שני, אם בתמונה נעשה שימוש רק בכמה צבעים, שימוש בלוח צבעים גדול הוא פשוט בזבוז של ביטים יקרים!
לאחר אופטימיזציה של הנתונים שמאוחסנים בפיקסלים בודדים, אפשר להשתמש בשיטות מתוחכמות יותר ולבדוק גם את הפיקסלים הסמוכים: מתברר שבתמונות רבות, ובמיוחד בתמונות, יש הרבה פיקסלים סמוכים עם צבעים דומים – למשל, השמיים, טקסטורות חוזרות וכו'. בעזרת המידע הזה, הדחיסה יכולה להשתמש בקידוד דלתא, שבו במקום לאחסן את הערכים הנפרדים של כל פיקסל, אפשר לאחסן את ההבדל בין הפיקסלים הסמוכים: אם הפיקסלים הסמוכים זהים, הערך של הדלתא הוא 'אפס' וצריך לאחסן רק ביט אחד! אבל למה לעצור כאן…
לעין האנושית יש רמות שונות של רגישות לצבעים שונים: תוכלו לבצע אופטימיזציה של קידוד הצבעים כדי להביא זאת בחשבון על ידי צמצום או הגדלת הצבעים בצבעים האלה. הפיקסלים 'בקרבת מקום' יוצרים רשת דו-ממדית. המשמעות היא שלכל פיקסל יש כמה שכנים: אפשר להשתמש בעובדה הזו כדי לשפר עוד יותר את קידוד הדלתא. במקום להסתכל רק על השכנים המיידיים של כל פיקסל, אפשר להסתכל על בלוקים גדולים יותר של פיקסלים בסביבה ולקודד בלוקים שונים עם הגדרות שונות.
כפי שאפשר לראות, אופטימיזציה של תמונות הופכת למסובכת במהירות (או מהנה, תלוי אתם), והיא תחום פעיל של מחקר אקדמי ומסחרי. תמונות תופסות הרבה בייט, ויש הרבה ערך בפיתוח שיטות טובות יותר לדחיסת תמונות. מידע נוסף זמין בדף בוויקיפדיה, או בסקירה המפורטת על שיטות דחיסת WebP, שבה מופיעה דוגמה מעשית.
שוב, כל זה מצוין, אבל גם מאוד אקדמי: איך זה עוזר לכם לבצע אופטימיזציה של התמונות באתר? חשוב להבין את צורת הבעיה: פיקסלים בפורמט RGBA, עומק ביט ודרכים שונות לביצוע אופטימיזציה. חשוב להבין את כל המושגים האלה ולזכור אותם לפני שמתחילים להיכנס לעומק של הדיונים על פורמטים שונים של תמונות רסטר.
דחיסת תמונות ללא אובדן נתונים לעומת דחיסת תמונות עם אובדן נתונים
בסוגים מסוימים של נתונים, כמו קוד מקור לדף או קובץ הפעלה, חשוב מאוד שכלי המדחס לא ישנה או יאבד את המידע המקורי: פיסת נתונים אחת חסרה או שגויה עלולה לשנות לחלוטין את המשמעות של תוכן הקובץ, או גרוע מזה, לפרוץ אותו לגמרי. לגבי סוגים אחרים של נתונים, כמו תמונות, אודיו ווידאו, יכול להיות שאפשר לספק ייצוג "משוער" של הנתונים המקוריים.
למעשה, בגלל אופן הפעולה של העין, לרוב אפשר להיפטר מחלק מהמידע על כל פיקסל כדי לצמצם את גודל הקובץ של התמונה. לדוגמה, לעין יש רגישות שונה לצבעים שונים, כך שאפשר להשתמש בפחות ביטים כדי לקודד צבעים מסוימים. כתוצאה מכך, צינור עיבוד נתונים אופטימלי לתמונות מורכב משני שלבים ברמה גבוהה:
- התמונה עוברת עיבוד באמצעות מסנן עם אובדן נתונים שמסיר חלק מנתוני הפיקסלים.
- התמונה עוברת עיבוד באמצעות מסנן ללא אובדן נתונים שמצמצם את נתוני הפיקסלים.
השלב הראשון הוא אופציונלי, והאלגוריתם המדויק תלוי בפורמט התמונה הספציפי, אבל חשוב להבין שכל תמונה יכולה לעבור שלב של דחיסת נתונים מסוג Lossy כדי להקטין את הגודל שלה. למעשה, ההבדל בין פורמטים שונים של תמונות, כמו GIF, PNG, JPEG ופורמטים אחרים, הוא בשילוב של האלגוריתמים הספציפיים שבהם הם משתמשים (או מוותרים עליהם) כשהם מחילים את השלבים של דחיסת נתונים עם אובדן נתונים (lossy) ודחיסת נתונים ללא אובדן נתונים (lossless).
אז מהי ההגדרה 'אופטימלית' של אופטימיזציה עם אובדן נתונים ואופטימיזציה ללא אובדן נתונים? התשובה תלויה בתוכן התמונה ובקריטריונים שלכם, כמו הפשרה בין גודל הקובץ לבין פגמים שנוצרים כתוצאה מדחיסת נתונים עם אובדן מידע: במקרים מסוימים, כדאי לדלג על אופטימיזציה עם אובדן מידע כדי להעביר פרטים מורכבים באיכות מלאה. במקרים אחרים, יכול להיות שתוכלו לבצע אופטימיזציה אגרסיבית לאיבוד נתונים כדי להקטין את גודל הקובץ של נכס התמונות. כאן נכנסים לתמונה השיקול וההקשר שלכם – אין הגדרה אוניברסלית אחת.
דוגמה מעשית: כשמשתמשים בפורמט עם אובדן נתונים כמו JPEG, בדרך כלל הדחיסה תציג הגדרת 'איכות' שניתן להתאים אישית (לדוגמה, פס ההזזה של האיכות שמסופק על ידי הפונקציונליות 'שמירה לאינטרנט' ב-Adobe Photoshop). בדרך כלל, האיכות היא מספר בין 1 ל-100 שקובע את האופן שבו פועלת האוסף הספציפי של האלגוריתמים עם אובדן נתונים ושל האלגוריתמים ללא אובדן נתונים. כדי לקבל את התוצאות הטובות ביותר, כדאי להתנסות בהגדרות איכות שונות של התמונות, ואל תחששו להוריד את רמת האיכות – התוצאות החזותיות הן לרוב טובות מאוד והחיסכון בגודל הקובץ יכול להיות גדול מאוד.
ההשפעה של דחיסת תמונות על מדדי הליבה לבדיקת חוויית המשתמש באתר
תמונות הן לרוב מועמדות להמהירות שבה נטען רכיב התוכן הכי גדול, ולכן הפחתת משך הטעינה של המשאבים של תמונה יכולה להוביל לשיפור של LCP גם במעבדה וגם בשטח.
כשמשנים את הגדרות הדחיסה בפורמטים של תמונות רסטר, חשוב להתנסות בפורמטים WebP ו-AVIF כדי לבדוק אם אפשר להציג את אותה תמונה בנפח קטן יותר בהשוואה לפורמטים ישנים יותר.
עם זאת, חשוב להיזהר שלא לצמצם יתר על המידה תמונות רסטר. פתרון טוב הוא להשתמש ב-CDN לאופטימיזציית תמונות כדי למצוא את הגדרות הדחיסה הטובות ביותר בשבילכם. לחלופין, אפשר להשתמש בכלים כמו Butteraugli כדי להעריך את ההבדלים החזותיים, וכך לא לקודד תמונות באופן אגרסיבי מדי ולפגוע באיכות שלהן יותר מדי.
רשימת משימות לאופטימיזציה של תמונות
ריכזנו כאן כמה טיפים ושיטות שכדאי לזכור כשמבצעים אופטימיזציה של התמונות:
- עדיפות לפורמטים וקטוריים: תמונות וקטוריות הן עצמאיות מבחינת רזולוציה וקנה מידה, ולכן הן מתאימות במיוחד לעולם של מכשירים מרובים ורזולוציה גבוהה.
- צמצום וקידוד של נכסי SVG: סימון XML שנוצר על ידי רוב האפליקציות לציור מכיל לרוב מטא-נתונים מיותרים שאפשר להסיר. חשוב לוודא שהשרתים מוגדרים כך שיפעילו דחיסת GZIP על נכסי SVG.
- עדיף להשתמש ב-WebP או ב-AVIF במקום בפורמטים רסטר ישנים יותר: בדרך כלל, תמונות WebP ותמונות AVIF יהיו קטנות בהרבה מפורמטים ישנים יותר של תמונות.
- בחירת הפורמט הטוב ביותר לקובץ תמונה רסטר: קובעים את הדרישות הפונקציונליות ובוחרים את הפורמט שמתאים לכל נכס ספציפי.
- התנסות עם הגדרות איכות אופטימליות לפורמטים של רשת נקודות: אל תחששו להפחית את הגדרות ה'איכות'. לרוב, התוצאות טובות מאוד והחיסכון בבייטים משמעותי.
- להסיר מטא-נתונים מיותרים של תמונות: תמונות רבות בפורמט רשת נתונים מכילות מטא-נתונים מיותרים לגבי הנכס: מידע גיאוגרפי, פרטי מצלמה וכן הלאה. צריך להשתמש בכלים המתאימים כדי להסיר את הנתונים האלה.
- הצגת תמונות מותאמות: משנים את הגודל של התמונות ומוודאים שהגודל 'להצגה' קרוב ככל האפשר לגודל 'הטבעי' של התמונה. חשוב לשים לב במיוחד לתמונות גדולות, כי הן גורמות לעלויות הכי גבוהות כשמשנים את הגודל שלהן.
- אוטומציה, אוטומציה, אוטומציה: כדאי להשקיע בכלים ובתשתית אוטומטיים שיבטיחו שכל נכסי התמונות שלכם יהיו תמיד מותאמים בצורה אופטימלית.