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

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

  • מגוון רחב של מכשירים בפורמטים שונים.
  • רוחב פס מוגבל ברשת וחיי סוללה.

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

אם אפשר, הימנעו משימוש בתמונות

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

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

רקע

היסטוריה קצרה מאוד של צפיפות התצוגה

בימים הראשונים, צפיפות הפיקסלים במסכי המחשב הייתה 72 או 96dpi (נקודות לאינץ').

צפיפות הפיקסלים במסכים השתפרה בהדרגה, בעיקר בגלל התרחיש לדוגמה של שימוש בנייד, שבו המשתמשים בדרך כלל מחזיקים את הטלפון קרוב יותר לפניהם, כך שהפיקסלים גלויים יותר. עד שנת 2008, טלפונים ברזולוציה של 150dpi היו הנורמה החדשה. המגמה של צפיפות תצוגה גבוהה יותר נמשכה, והטלפונים החדשים של היום כוללים תצוגות של 300dpi (המותג של Apple הוא 'Retina').

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

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

בבון 1x
Baboon 2x
בבונים! ברמות שונות של צפיפות פיקסלים.

פיקסלים באינטרנט

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

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

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

חישוב יחס הפיקסלים של המכשיר

נניח שלטלפון חכם יש מסך עם מסך פיזי של 180 פיקסלים לאינץ' (PP). החישוב של יחס הפיקסלים של המכשיר כולל שלושה שלבים:

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

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

  2. כדי לקבל את צפיפות הפיקסלים האידיאלית למרחק הנתון, צריך להכפיל את יחס המרחק בצפיפות הרגילה (96ppi).

    idealPixelDensity = (28/18) * 96 = 150 פיקסלים לאינץ' (כמעט)

  3. כדי לקבל את יחס הפיקסלים של המכשיר, מחלקים את צפיפות הפיקסלים הפיזית בצפיפות הפיקסלים האידיאלית.

    devicePixelRatio = 180/150 = 1.2

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

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

physicalPixels = window.devicePixelRatio * idealPixels

בעבר, ספקי מכשירים נטו לעגל את הערכים של devicePixelRatios (DPR). ב-iPhone וב-iPad של Apple מדווחים על צפיפות פיקסלים של 1, ובמכשירים המקבילים עם מסך Retina מדווחים על צפיפות פיקסלים של 2. במפרט CSS מומלץ

יחידת הפיקסלים מתייחסת למספר השלם של פיקסלים במכשיר שהכי קרוב לפיקסל העזר.

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

עם זאת, בעולם המכשירים הרבה יותר מגוונים, ובטלפונים עם Android יש בדרך כלל ערכי DPR של 1.5. הטאבלט Nexus 7 כולל DPR של כ-1.33, שנגיע אליו באמצעות חישוב דומה לזה שלמעלה. בעתיד נוסיף עוד מכשירים עם שיעורי הכנסה משתנים. לכן, לעולם אל תניחו שללקוחות שלכם יהיו ערכי DPR שלמים.

סקירה כללית של טכניקות לתמונות HiDPI

יש הרבה שיטות לפתרון הבעיה של הצגת התמונות באיכות הטובה ביותר במהירות האפשרית, והן נחלקות לשתי קטגוריות עיקריות:

  1. אופטימיזציה של תמונות בודדות, וגם
  2. אופטימיזציה של הבחירה בין כמה תמונות.

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

  • תמונה דחוסה מאוד ב-HiDPI
  • פורמט תמונה מעולה
  • פורמט תמונה הדרגתית

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

  • JavaScript
  • העברה בצד השרת
  • שאילתות מדיה של CSS
  • תכונות מובנות בדפדפן (image-set(), <img srcset>)

תמונה דחוסה מאוד ב-HiDPI

תמונות כבר מהוות 60% מרוחב הפס שמושקע בהורדת אתר ממוצע. הצגת תמונות HiDPI לכל הלקוחות תגדיל את המספר הזה. עד כמה הוא יגדל?

הרצתי כמה בדיקות שיצרו מקטעים של תמונה 1x ו-2x באיכות JPEG, עם 90, 50 ו-20. זהו סקריפט המעטפת שהשתמשתי בו (באמצעות ImageMagick) כדי ליצור אותם:

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

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

כמובן, הצגת תמונות באיכות נמוכה ודחוסה מאוד בגודל 2x למכשירים 2x גרועה יותר מהצגת תמונות באיכות גבוהה יותר, והגישה שלמעלה גורמת לסנקציות על איכות התמונה. אם משווים בין תמונות באיכות: 90 לתמונות באיכות: 20, רואים ירידה ברמת החדות ועלייה בגרעיניות. יכול להיות שהארטיפקטים האלה לא יתקבלו במקרים שבהם תמונות באיכות גבוהה הן קריטיות (לדוגמה, אפליקציית צפייה בתמונות), או למפתחי אפליקציות שלא מוכנים להתפשר.

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

פורמט תמונה נהדר

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

אחת הדרכים לבדוק אם יש תמיכה ב-WebP היא באמצעות JavaScript. אתם טוענים תמונה בגודל 1px באמצעות data-uri, ממתינים לאירועי טעינה או שגיאה ואז מוודאים שהגודל נכון. המוצר Modernizr מגיע עם סקריפט לזיהוי תכונות, שזמין דרך Modernizr.webp.

עם זאת, דרך טובה יותר לעשות זאת היא ישירות ב-CSS באמצעות הפונקציה image()‎. לכן, אם יש לכם תמונה בפורמט WebP וחלופה ל-JPEG, תוכלו לכתוב את הקוד הבא:

#pic {
  background: image("foo.webp", "foo.jpg");
}

לגישה הזו יש כמה בעיות. ראשית, image() לא מיושם באופן נרחב. שנית, אמנם הדחיסה של WebP משאירה את JPEG מאחור, אבל עדיין מדובר בשיפור מצטבר יחסית – הגודל שלהן קטן ב-30% בהתאם לגלריית WebP הזו. לכן, WebP לבד לא מספיק כדי לטפל בבעיה של ה-DPI הגבוה.

פורמטים של תמונות פרוגרסיביות

לפורמטים מסוג Progressive תמונה כמו JPEG 2000, Progressive JPEG, Progressive PNG ו-GIF, יש יתרון (קצת שנוי במחלוקת) – לראות את התמונה נכנסת לתמונה לפני שהיא נטענת במלואה. יכול להיות שיהיה להם קצת יתרת מקום, אבל יש עדויות סותרות בנושא הזה. לטענת Jeff Atwood, המצב המתקדם "מוסיפה כ-20% לגודל של תמונות PNG וכ-10% לגודל של תמונות JPEG ו-GIF". עם זאת, Stoyan Stefanovטען שבקבצים גדולים, מצב הדרגתי יעיל יותר (ברוב המקרים).

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

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

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

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

שימוש ב-JavaScript כדי לקבוע איזו תמונה לטעון

הגישה הראשונה והבולטת ביותר להחליט איזו תמונה לטעון היא להשתמש ב-JavaScript אצל הלקוח. כך תוכלו לגלות את כל המידע על סוכן המשתמש שלכם ולעשות את הדבר הנכון. אפשר לקבוע את יחס הפיקסלים במכשיר באמצעות window.devicePixelRatio, לקבל מידע על הרוחב והגובה של המסך, ואפילו לבצע סריקה של חיבור לרשת באמצעות navigator.connection או שליחה של בקשה מזויפת, כמו ש-foresight.js עושה. אחרי שאוספים את כל המידע הזה, אפשר להחליט איזו תמונה לטעון.

יש בערך מיליון ספריות JavaScript שעושות משהו כמו שלמעלה, ולצערנו אף אחת מהן לא יוצאת מן הכלל.

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

בחירת התמונה שתישאר בשרת

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

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

שימוש בשאילתות מדיה של CSS

שאילתות מדיה ב-CSS הן פונקציונליות, ולכן הן מאפשרות לכם לציין את הכוונה שלכם ולאפשר לדפדפן לבצע את הפעולה הנכונה בשמכם. בנוסף לשימוש הנפוץ ביותר בשאילתות מדיה – התאמה לגודל המכשיר – אפשר גם להתאים ל-devicePixelRatio. שאילתה המדיה המשויכת היא device-pixel-ratio, ויש לה וריאנטים משויכים של מינימום ומקסימום, כצפוי. אם רוצים לטעון תמונות ב-DPI גבוה ויחס הפיקסלים של המכשיר חורג מהסף, צריך לבצע את הפעולות הבאות:

#my-image { background: (low.png); }

@media only screen and (min-device-pixel-ratio: 1.5) {
  #my-image { background: (high.png); }
}

התהליך קצת יותר מורכב משילוב בין כל הקידומות של הספקים, במיוחד בגלל הבדלים מטורפים במיקום של הקידומות 'min' ו-'max':

@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {

  #my-image {
    background:url(high.png);
  }
}

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

לצערנו, עדיין קשה להשתמש בו, והוא מוביל לקוד CSS שנראה מוזר (או מחייב עיבוד מקדים). בנוסף, הגישה הזו מוגבלת למאפייני CSS, כך שאין דרך להגדיר <img src>, וכל התמונות צריכות להיות אלמנטים עם רקע. לבסוף, אם תסתמכו רק על יחס הפיקסלים של המכשיר, יכול להיות שתגיעו למצב שבו הטלפון החכם עם רזולוציית המסך הגבוהה (DPI) יוריד נכס תמונה גדול בגודל 2x בזמן חיבור EDGE. זו לא חוויית המשתמש הטובה ביותר.

שימוש בתכונות חדשות בדפדפן

לאחרונה התנהלו דיונים רבים בנושא תמיכה בפלטפורמות אינטרנט בבעיה של תמונות ברזולוציה גבוהה (DPI). לאחרונה, Apple נכנסה לתחום הזה והוסיפה את פונקציית ה-CSS image-set()‎ ל-WebKit. לכן, גם Safari וגם Chrome תומכים בו. מכיוון שזו פונקציית CSS, image-set() לא פותרת את הבעיה בתגים <img>. מזינים את הכתובת @srcset, שמתייחסת לבעיה הזו, אבל (נכון למועד הכתיבה) אין לה הטמעות של קובצי עזר (עדיין!). בקטע הבא נרחיב על image-set ו-srcset.

תכונות בדפדפן לתמיכה ברזולוציית DPI גבוהה

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

ראשית, מה ההבדל בין שני סוגי התוכן? ובכן, image-set() היא פונקציית CSS, שמתאימה לשימוש כערך של מאפיין ה-CSS ברקע. srcset הוא מאפיין ספציפי לרכיבי <img> עם תחביר דומה. שני התגים האלה מאפשרים לציין הצהרות על תמונות, אבל באמצעות המאפיין srcset אפשר גם להגדיר איזו תמונה תיטען על סמך גודל שדה התצוגה.

שיטות מומלצות לשימוש ב-image-set

פונקציית ה-CSS image-set() זמינה עם הקידומת -webkit-image-set(). התחביר פשוט למדי, והוא כולל הצהרה אחת או יותר על תמונות מופרדות בפסיקים, שמכילות מחרוזת של כתובת URL או פונקציית url() ואחריה הרזולוציה המשויכת. לדוגמה:

background-image:  -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

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

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

במקום לציין 1x,‏ 1.5x או Nx, אפשר גם לציין צפיפות פיקסלים מסוימת של המכשיר ב-dpi.

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

background-image: url(icon1x.jpg);
background-image: -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);
/* This will be useful if image-set gets into the platform, unprefixed.
    Also include other prefixed versions of this */
background-image: image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

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

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

בשלב הזה, יכול להיות שתתהו למה לא פשוט להשתמש ב-polyfill (כלומר ליצור תוסף JavaScript) ל-image-set() ולהפסיק שם? מסתבר שקשה מאוד להטמיע polyfills יעילים לפונקציות CSS. (בשיחה הזו בנושא www-style תוכלו לקרוא הסבר מפורט על הסיבה לכך).

srcset של תמונה

דוגמה ל-srcset:

<img alt="my awesome image"
  src="banner.jpeg"
  srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">

כפי שאפשר לראות, בנוסף להצהרות x ש-image-set מספק, רכיב srcset מקבל גם ערכים של w ו-h שתואמים לגודל של חלון התצוגה, בניסיון להציג את הגרסה הרלוונטית ביותר. ההגדרה הזו תציג את banner-phone.jpeg במכשירים עם רוחב שדה צפייה של פחות מ-640 פיקסלים, את banner-phone-HD.jpeg במכשירים עם מסך קטן ורזולוציית DPI גבוהה, את banner-HD.jpeg במכשירים עם רזולוציית DPI גבוהה ומסך גדול מ-640 פיקסלים ואת banner.jpeg בכל שאר המכשירים.

שימוש בהגדרה 'תמונה' לרכיבי תמונה

מאחר שמאפיין srcset ברכיבי img לא מוטמע ברוב הדפדפנים, יכול להיות שתתפתתו להחליף את רכיבי ה-img ברכיבי <div> עם רקעים ולהשתמש בגישה של image-set. זה יפעל, עם כמה תנאים. החיסרון הוא שלתג <img> יש ערך סמנטי לטווח ארוך. בפועל, הדבר חשוב בעיקר לסורק האינטרנט ולסיבות של נגישות.

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

<div id="my-content-image"
  style="content: -webkit-image-set(
    url(icon1x.jpg) 1x,
    url(icon2x.jpg) 2x);">
</div>

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

מילוי פוליגונים ל-srcset

תכונה שימושית אחת של srcset היא שהיא מגיעה עם חלופה טבעית. אם לא מטמיעים את המאפיין srcset, כל הדפדפנים יודעים לעבד את המאפיין src. בנוסף, מכיוון שמדובר רק במאפיין HTML, אפשר ליצור polyfills באמצעות JavaScript.

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

הדגמה של ה-polyfill בפעולה.

סיכום

אין פתרון קסם לבעיה של תמונות עם DPI גבוה.

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

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

לסיכום, ההמלצות שלי הן: