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

איליה גריגוריק
איליה גריגוריק

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

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

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

כל הדפדפנים המודרניים תומכים ב-Scalable Vector Graphics (SVG), שהוא פורמט תמונה מבוסס-XML לגרפיקה דו-ממדית. אתם יכולים להטמיע את תגי העיצוב של 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. התמונה מעובדת באמצעות מסנן losy, שמונע נתוני פיקסלים מסוימים.
  2. התמונה מעובדת באמצעות מסנן lossless שדוחס את נתוני הפיקסלים.

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

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

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

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

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

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

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

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

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

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