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

בוריס סמוס
בוריס סמוס

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

  • מגוון גדול של מכשירים עם גורמי צורה שונים.
  • רוחב פס מוגבל וחיי סוללה.

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

מומלץ להימנע משימוש בתמונות

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

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

רקע

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

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

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

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

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

בבון 1x
בבון 2x
בבונים! בדחיסות פיקסלים שונה.

Pixel באינטרנט

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

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

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

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

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

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

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

  2. מכפילים את יחס המרחק בדחיסות הסטנדרטית (96PPI) כדי לקבל את דחיסות הפיקסלים האידיאלית למרחק הנתון.

    אידיאלית'פיקסלים = (28/18) * 96 = 150 פיקסלים לאינץ' (בערך)

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

    devicePixelRatio = 180/150 = 1.2

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

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

physicalPixels = window.devicePixelRatio * idealPixels

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

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

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

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

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

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

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

פורמט תמונה מעולה

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

אחת הדרכים היא לבדוק אם יש תמיכה ב-WebP היא באמצעות JavaScript. אתם טוענים תמונה בגודל 1 פיקסלים דרך data-uri, ממתינים שאירועי השגיאה יופעלו או שאירועי השגיאה יופעלו ולאחר מכן מוודאים שהגודל נכון. משחק מודרני כולל סקריפט לזיהוי תכונות, שזמין דרך 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, הוא העובדה שהתמונה נכנסת למקום לפני שהיא נטענת במלואה. הן עשויות לצבור תקורה מסוימת, למרות שיש עדויות סותרות בנושא. ג'ף אטווד טען שהמצב המתקדם "מוסיף כ-20% לגודל של תמונות PNG וכ-10% לגודל תמונות JPEG ו-GIF". עם זאת, סטויאן סטפנוב טען שעבור קבצים גדולים, מצב מתקדם הוא יעיל יותר (ברוב המקרים).

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

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

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

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

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

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

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

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

החלט איזו תמונה לטעון בשרת

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

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

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

בהיותו מוצהר, שאילתות מדיה של CSS מאפשרות לכם להצהיר על הכוונה שלכם ולאפשר לדפדפן לעשות את הדבר הנכון בשמכם. בנוסף לשימוש הנפוץ ביותר בשאילתות מדיה, התאמה לגודל המכשיר, ניתן לך גם להתאים את devicePixelRatio. שאילתת המדיה המשויכת היא יחס-פיקסלים במכשיר, ויש לה גרסאות מינימליות ומקסימליות, כפי שניתן לצפות. אם רוצים לטעון תמונות עם 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 גבוה יוריד נכס תמונה ענקי פי 2 כשהוא מחובר לחיבור 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 מאפשר גם להגדיר איזו תמונה תיטען בהתאם לגודל אזור התצוגה.

שיטות מומלצות להגדרת תמונות

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

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

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

בנוסף לטעינת התמונה הנכונה, הדפדפן גם יקטין אותה בהתאם. במילים אחרות, הדפדפן מניח ששתי תמונות גדולות פי 2 מתמונות בגודל פי 1, ולכן המערכת תקטין את התמונה פי 2 בפקטור של 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
);

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

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

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

תמונה של 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 שתואמים לגודל של אזור התצוגה, בניסיון להציג את הגרסה הרלוונטית ביותר. הקוד למעלה יציג באנר-phone.jpeg למכשירים שרוחב התצוגה שלהם הוא פחות מ-640 פיקסלים, מודעת באנר-טלפון-HD.jpeg למכשירים עם מסך קטן עם DPI גבוה, banner-HD.jpeg למכשירים עם DPI גבוה עם מסכים גדולים מ-640px, ו-banner.jpeg לכל השאר.

שימוש בקבוצת תמונות לרכיבי תמונה

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

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

מילוי Polyfilling srcset

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

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

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

סיכום

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

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

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

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

  • לתמונות רקע, צריך להשתמש במאפיין image-set עם החלופות המתאימות לדפדפנים שלא תומכים בו.
  • לתמונות של התוכן, השתמשו ב-srcset polyfill או חזרה לשימוש ב-image-set (ראו למעלה).
  • במצבים שבהם אתם מוכנים לוותר על איכות התמונה, כדאי לשקול להשתמש בתמונות דחוסות פי 2.