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

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

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

אופטימיזציה של תמונות וקטוריות

כל הדפדפנים המודרניים תומכים בפורמט 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) ערוץ כחול ו-(A) ערוץ אלפא (שקיפות).

באופן פנימי, הדפדפן מקצה 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 בייטים לכל פיקסל.

פגמים שנובעים מדחיסת נתונים
משמאל לימין (PNG): 32 ביט (16 מיליון צבעים), 7 ביט (128 צבעים), 5 ביט (32 צבעים).

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

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

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

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

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

דחיסת תמונות ללא אובדן נתונים לעומת דחיסת תמונות עם אובדן נתונים

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

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

  1. התמונה עוברת עיבוד באמצעות מסנן אובדן נתונים שמחסל חלק מנתוני הפיקסלים.
  2. התמונה עוברת עיבוד באמצעות מסנן ללא אובדן נתונים שמצמצם את נתוני הפיקסלים.

השלב הראשון הוא אופציונלי, והאלגוריתם המדויק יהיה תלוי בפורמט התמונה הספציפי, אבל חשוב להבין שכל תמונה יכולה לעבור שלב של דחיסת נתונים עם אובדן נתונים כדי לצמצם את הגודל שלה. למעשה, ההבדל בין פורמטים שונים של תמונות, כמו GIF,‏ PNG,‏ JPEG ופורמטים אחרים, הוא בשילוב של האלגוריתמים הספציפיים שבהם הם משתמשים (או מוותרים עליהם) כשהם מחילים את השלבים של דחיסת נתונים עם אובדן נתונים ושל דחיסת נתונים ללא אובדן נתונים.

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

דוגמה מעשית: כשמשתמשים בפורמט עם אובדן נתונים כמו JPEG, בדרך כלל הדחיסה תציג הגדרת 'איכות' שניתן להתאים אישית (לדוגמה, פס ההזזה של האיכות שמסופק על ידי הפונקציונליות 'שמירה לאינטרנט' ב-Adobe Photoshop). בדרך כלל, האיכות היא מספר בין 1 ל-100 שקובע את האופן שבו פועלת האוסף הספציפי של האלגוריתמים עם אובדן נתונים ושל האלגוריתמים ללא אובדן נתונים. כדי לקבל את התוצאות הטובות ביותר, מומלץ להתנסות בהגדרות איכות שונות של התמונות, ואל תחששו להוריד את רמת האיכות – התוצאות החזותיות הן לרוב טובות מאוד והחיסכון בגודל הקובץ יכול להיות גדול מאוד.

ההשפעה של דחיסת תמונות על מדדי הליבה לבדיקת חוויית המשתמש באתר

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

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

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

רשימת משימות לאופטימיזציה של תמונות

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

  • עדיפות לפורמטים וקטוריים: תמונות וקטוריות הן עצמאיות ברזולוציה ובקנה מידה, ולכן הן מתאימות במיוחד לעולם של מכשירים מרובים ורזולוציה גבוהה.
  • צמצום וקידוד של נכסי SVG: סימון XML שנוצר על ידי רוב האפליקציות לציור מכיל לרוב מטא-נתונים מיותרים שאפשר להסיר. חשוב לוודא שהשרתים מוגדרים כך שיפעילו דחיסת GZIP על נכסי SVG.
  • עדיף להשתמש ב-WebP או ב-AVIF במקום בפורמטים רסטר ישנים יותר: בדרך כלל, WebP ותמונות AVIF יהיו קטנות בהרבה מפורמטים ישנים יותר של תמונות.
  • בחירת הפורמט הטוב ביותר לקובץ תמונה רסטר: קובעים את הדרישות הפונקציונליות ובוחרים את הפורמט שמתאים לכל נכס ספציפי.
  • כדאי להתנסות בהגדרות האיכות האופטימליות לפורמטים רסטר: אל תחששו להוריד את ההגדרות של 'איכות', לרוב התוצאות טובות מאוד והחיסכון בייטים משמעותי.
  • הסרת מטא-נתונים מיותרים של תמונות: תמונות רסטר רבות מכילות מטא-נתונים מיותרים לגבי הנכס: מידע גיאוגרפי, פרטי מצלמה וכו'. צריך להשתמש בכלים המתאימים כדי להסיר את הנתונים האלה.
  • הצגת תמונות מותאמות: משנים את הגודל של התמונות ומוודאים שהגודל 'להצגה' קרוב ככל האפשר לגודל 'הטבעי' של התמונה. חשוב לשים לב במיוחד לתמונות גדולות, כי הן גורמות לעלויות הכי גבוהות כשמשנים את הגודל שלהן.
  • אוטומציה, אוטומציה, אוטומציה: כדאי להשקיע בכלים ובתשתית אוטומטיים שיבטיחו שכל נכסי התמונות שלכם יהיו תמיד מותאמים בצורה אופטימלית.