צגים עם צפיפות פיקסלים גבוהה הופכים במהירות לנורמה. יוצרים של תוכן צריכים להתאים את עצמם לעובדה הזו. זהו מדריך קצר בנושא הצגת תמונות באיכות גבוהה באינטרנט, בלי 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](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/chrome-1x-a9a68850c7937.png?hl=he)
![PNG 1x](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/png-1x-afed10dc2611a.png?hl=he)
מידות טבעיות: 256x256px
, גודל הנכס: 31 kB
, פורמט: PNG
משוכנעים? טוב. עכשיו נשתמש בתמונה בצפיפות גבוהה. יכול להיות שתתפתתו לחסוך מקום על ידי שמירת הלוגו כקובץ JPEG, אבל זו לא תמיד רעיון טוב. שמירת סמלי לוגו וגרפיקה אחרת בפורמט עם אובדן נתונים נוטה לגרום לבעיות. במקרה הזה הגזמתי את הבעיה באמצעות דחיסת תמונה ברמה גבוהה מאוד, אבל אפשר לראות את הפסים בצבעים כהים, את הנקודות ברקעים לבנים ואת הקווים המבולבלים:
![Chrome 2x](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/chrome-2x-ea62989ff12fa.jpg?hl=he)
![Jpeg 2x](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/jpeg-2x-237af74b36cec.png?hl=he)
מידות טבעיות: 512x512px
, גודל הנכס: 13 kB
, פורמט: JPEG
בתמונות קטנות יחסית, מומלץ להשתמש ב-2 קובצי PNG. חשוב לזכור שההבדל בגודל בין קובץ PNG בגודל 1x לבין קובץ PNG בגודל 2x הוא בדרך כלל גדול מאוד (52KB במקרה הזה). עם זאת, במקרה של לוגו, הוא הפנים של האתר והדבר הראשון שהמבקרים יראו. אם תתפשרו יותר מדי על האיכות כדי להגדיל את התמונה, היא תהיה גם הדבר האחרון שהמבקרים יראו.
זהו הלוגו של Chrome במלוא הדרו, בגודל של מחצית מהמידות הטבעיות שלו במסכים עם רזולוציה כפולה:
![Chrome 2x](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/chrome-2x-29ed7771d72a4.png?hl=he)
![Png 2x](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/png-2x-b342295f0753a.png?hl=he)
מידות טבעיות: 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](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/chrome-2x-8bit-2577f04296d9d.png?hl=he)
![PNG 2x 8bit](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/png-2x-8bit-a92907fc6d62d.png?hl=he)
מידות טבעיות: 512x512px
, גודל הנכס: 13 kB
, פורמט: PNG,
8-bit palette
תמונות עם מגוון צבעים
כתבתי מאמר ב-HTML5Rocks שבו סקירה של כמה שיטות שונות לתמונות עם תגובה דינמית, וערךתי מחקר בנושא דחיסת JPEG ברזולוציות 1x ו-2x והשוואה בין הגדלים והאיכות החזותית של התוצאות. זהו אחד מהאריחים האלה מהמאמר שלמעלה:
![אריח.](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/tile-8d12098c74e3b.jpg?hl=he)
סימנתי את התמונות לפי רמת הדחיסה שלהן (המצוינת באיכות ה-JPEG), הגודל שלהן (בבייטים) והדעה הסובייקטיבית שלי לגבי איכות התמונה בהשוואה לתמונה המקורית (הדרוג לפי מספרים). החלק המעניין הוא שהתמונה ברזולוציה כפולה (2x) שנדחסה מאוד (מסומנת ב-3) קטנה יותר ונראית טוב יותר מאשר התמונה ברזולוציה רגילה (1x) שלא דחוסה (מסומנת ב-4). במילים אחרות, בין התמונות 4 ו-3 הצלחנו לשפר את איכות התמונה על ידי הכפלת כל אחת מהמידות והגברת הדחיסה באופן משמעותי, ובמקביל לצמצם את הגודל ב-2KB.
דחיסה, מאפיינים ואיכות חזותית
רציתי לקבל תובנות נוספות לגבי הפשרות בין רמת הדחיסה, מידות התמונה, האיכות החזותית וגודל התמונה. על סמך המחקר שלמעלה, הרצתי מחקר עם ההשערה הבאה:
השערה
עם דחיסת נתונים מספקת, תמונה בגודל 2x תיראה זהה לאותה תמונה בגודל 1x עם דחיסת נתונים אחרת (נמוכה יותר). עם זאת, במקרה כזה, התמונה ברזולוציה כפולה ודחוסה מאוד תהיה קטנה יותר מהתמונה ברזולוציה אחת.
התהליך
- נתונה תמונה ביחס גובה-רוחב של 2x, יוצרים את התמונה ביחס גובה-רוחב של 1x.
- דחיסת שתי התמונות ברמות שונות.
- יוצרים דף בדיקה שבו מוצגות שתי קבוצות התמונות זו לצד זו.
- מחפשים את המקום בשתי הקבוצות שבו התמונות זהות.
- שימו לב לגודלי התמונות ולרמות הדחיסה המקבילות.
- נסו את זה גם במסך 1x וגם במסך 2x.
יצרתי אפליקציה להשוואה של תמונות זו לצד זו, בדומה לתצוגת ההשוואה של Lightroom. המטרה היא להציג תמונות בגודל 1x ו-2x זה לצד זה, אבל גם לאפשר לכם להגדיל את התצוגה של כל קטע בתמונה כדי לראות פרטים נוספים. אפשר גם לבחור בין הפורמטים JPEG ו-WebP ולשנות את איכות הדחיסה כדי לראות השוואות בין גודל הקובץ לבין איכות התמונה. הרעיון הוא לשנות את ההגדרות בכמה תמונות, לבדוק איזו איכות דחיסה, שינוי גודל ופורמט מול איכות התמונה מתאימה לכם, ולהשתמש בהגדרה הזו בכל התמונות.
![צילום מסך של השוואה](https://web.developers.google.cn/static/articles/easy-high-dpi-images/image/comparison-screenshot-8d5b8b680d356.png?hl=he)
הכלי עצמו זמין לניסוי. כדי להגדיל את התמונה, בוחרים אזור משנה להגדלה.
ניתוח
חשוב לציין כבר בהתחלה שאיכות התמונה היא עניין סובייקטיבי. בנוסף, סביר להניח שתרחיש השימוש הספציפי שלכם יקבע את סדר העדיפויות שלכם בספקטרום של איכות התצוגה לעומת גודל הקובץ. בנוסף, סוגים שונים של מאפייני תמונה מגיבים באופן שונה לשינוי קנה המידה ולאיכות הדחיסה, ולכן יכול להיות שפתרון אחד לא יתאים לכל המקרים. המטרה של הכלי היא לעזור לכם לפתח אינטואיציה לגבי דחיסת איכות התמונה, הפורמטים והמידות.
אחרי ששיחקתי עם הכלי להגדלת התמונות, הבנתי כמה דברים במהירות. קודם כול, אני מעדיף תמונות 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 בנושא דומה. שיהיה לך יום מצוין, ושהתמונות שלך יהיו חדות והשימוש בחבילת הגלישה יהיה נמוך!