תמונות עם DPI גבוה בקלות

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

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

banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x

למרות שמאפיין ה-CSS image-set משתמש ב-devicePixelRatio רק כדי להחליט איזו תמונה לטעון, הוא עדיין מאלץ את המפתחים לכתוב הרבה תגי markup נוספים לכל תמונה.

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

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

סיכום הקווים המנחים:

  • אם אפשר, השתמשו ב-CSS/SVG במקום בתמונות רסטר.
  • כברירת מחדל, כדאי להשתמש בתמונות שעברו אופטימיזציה למסכים עם צפיפות פיקסלים גבוהה.
  • מומלץ להשתמש בקובצי PNG לציורים פשוטים ולגרפיקת פיקסלים (למשל, סמלי לוגו).
  • כדאי להשתמש בקבצים דחוסים בפורמט JPEG לתמונות עם מגוון צבעים (למשל, תמונות).
  • תמיד צריך להגדיר גדלים מפורשים (באמצעות CSS או HTML) לכל רכיבי התמונות.

ציורים פשוטים ופיקסל ארט

בדרך כלל אפשר להימנע לחלוטין משימוש בתמונות קטנות באמצעות תכונות CSS או SVG. לדוגמה, אין צורך להשתמש בתמונות כדי ליצור פינות מעוגלות, כי למאפיין ה-CSS border-radius יש תמיכה רחבה. באופן דומה, יש תמיכה רחבה בגופנים מותאמים אישית, ולכן לא מומלץ להשתמש בטקסט 'בפורמט תמונה'.

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

Chrome 1x
PNG 1x

מידות טבעיות: 256x256px, גודל הנכס: 31 kB, פורמט: PNG

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

Chrome 2x
Jpeg 2x

מידות טבעיות: 512x512px, גודל הנכס: 13 kB, פורמט: JPEG

בתמונות קטנות יחסית, מומלץ להשתמש ב-2 קובצי PNG. חשוב לזכור שההבדל בגודל בין קובץ PNG בגודל 1x לבין קובץ PNG בגודל 2x הוא בדרך כלל גדול מאוד (52KB במקרה הזה). עם זאת, במקרה של לוגו, הוא הפנים של האתר והדבר הראשון שהמבקרים יראו. אם תתפשרו יותר מדי על האיכות כדי להגדיל את הגודל, זה יהיה גם הדבר האחרון שהמבקרים שלכם יראו.

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

Chrome 2x
PNG 2x

מידות טבעיות: 512x512px, גודל הנכס: 83 kB, פורמט: PNG

הקוד הבא יוצר את הרינדור שלמעלה:

<img src="chrome2x.png" style="width: 256px; height: 256px;"/>

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

אחת מהאפשרויות לאופטימיזציה שעשויה לפעול היא להקטין את קובץ ה-PNG של 24 ביט לקובץ של 8 ביט עם צבעים מתוך צבעים סטטיים. התכונה הזו פועלת בתמונות עם מספר קטן של צבעים, כולל הלוגו של Chrome. כדי לבצע את האופטימיזציה הזו, אפשר להשתמש בכלי כמו http://pngquant.org/. אפשר לראות כאן קצת פסים, אבל הקובץ הזה הוא רק 13KB, חיסכון עצום של פי 6 בהשוואה לקובץ ה-PNG המקורי בגודל 512x512.

Chrome 2x 8bit
PNG 2x 8bit

מידות טבעיות: 512x512px, גודל הנכס: 13 kB, פורמט: PNG, 8-bit palette

תמונות עם מגוון צבעים

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

כרטיס מידע.

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

דחיסה, מאפיינים ואיכות חזותית

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

השערה

עם דחיסת נתונים מספקת, תמונה בגודל 2x תיראה זהה לאותה תמונה בגודל 1x עם דחיסת נתונים אחרת (נמוכה יותר). עם זאת, במקרה כזה, התמונה ברזולוציה כפולה ודחוסה מאוד תהיה קטנה יותר מהתמונה ברזולוציה אחת.

התהליך

  • נתונה תמונה ביחס גובה-רוחב של 2x, יוצרים את התמונה ביחס גובה-רוחב של 1x.
  • דחיסת שתי התמונות ברמות שונות.
  • יוצרים דף בדיקה שבו מוצגות שתי קבוצות התמונות זו לצד זו.
  • מחפשים את המקום בשתי הקבוצות שבו התמונות זהות.
  • שימו לב לגודלי התמונות ולרמות הדחיסה המקבילות.
  • כדאי לנסות את התכונה גם במסך 1x וגם במסך 2x.

יצרתי אפליקציה להשוואה של תמונות זו לצד זו, בדומה לתצוגת ההשוואה של Lightroom. המטרה היא להציג תמונות בגודל 1x ו-2x זו לצד זו, אבל גם לאפשר לכם להגדיל את התצוגה של כל קטע בתמונה כדי לראות פרטים נוספים. אפשר גם לבחור בין הפורמטים JPEG ו-WebP ולשנות את איכות הדחיסה כדי לראות השוואות בין גודל הקובץ לבין איכות התמונה. הרעיון הוא לשנות את ההגדרות בכמה תמונות, לבדוק איזו איכות דחיסה, שינוי קנה מידה ופורמט מול איכות התמונה מתאימה לכם, ולהשתמש בהגדרה הזו בכל התמונות.

צילום מסך של השוואה

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

ניתוח

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

אחרי ששיחקתי עם הכלי להגדלת התמונות, הבנתי כמה דברים במהירות. קודם כול, אני מעדיף תמונות quality=30 dpr=2x על תמונות quality=90 dpr=1x בגלל רמת הפירוט הגבוהה יותר. גם גודל הקובץ של התמונות דומה (במקרה של המטוס, גודל הקובץ של התמונה הדחוסה ברזולוציה כפולה הוא 76KB, ואילו גודל הקובץ של התמונה הלא דחוסה ברזולוציה רגילה הוא 80KB).

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

תמונות WebP נראות הרבה יותר ברורות מאשר תמונות JPEG, במיוחד ברמות דחיסה נמוכות. נראה שהבעיה של פס הצבע הרבה פחות חמורה. לבסוף, תמונות WebP הן קומפקטיות הרבה יותר.

אזהרות ופירוט

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

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

לפני שנסיים, רציתי לציין כמה בעיות פתוחות:

  • ההשפעה של דחיסת נתונים גבוהה על הביצועים. מהן העונשים על פענוח של תמונות דחוסות מאוד?
  • מהן ההשלכות על הביצועים של שינוי גודל התמונה למטה כשתמונה בגודל 2x נטענת במסך בגודל 1x?

לסיכום, מומלץ להשתמש ב-CSS וב-SVG במקום בתמונות רסטר. אם אתם חייבים להשתמש בתמונות רסטר, השתמשו בפורמט PNG לתמונות עם לוחות צבעים מוגבלים וצבעים מוצקים רבים, ובפורמט JPEG לתמונות עם הרבה צבעים וצבעים מדורגים. היתרון הגדול של הגישה הזו הוא שהתווית לא משתנה כמעט בכלל. כל מה שמפתחי האתר צריכים לעשות הוא ליצור נכסים בגודל כפול ולהגדיר את הגודל של התמונות בצורה נכונה ב-DOM.

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