אחת מהתכונות של מגוון המכשירים המורכב של היום היא שיש מגוון רחב מאוד של דחיסות פיקסלים במסכים. במכשירים מסוימים יש מסכים ברזולוציה גבוהה מאוד, ובמכשירים אחרים הרזולוציה נמוכה יותר. מפתחי אפליקציות צריכים לתמוך במגוון דחיסות פיקסלים, וזו יכולה להיות משימה מאתגרת למדי. באינטרנט לנייד, האתגרים מורכבים מכמה גורמים:
- מגוון רחב של מכשירים בפורמטים שונים.
- רוחב פס מוגבל ברשת וחיי סוללה מוגבלים.
מבחינת תמונות, המטרה של מפתחי אפליקציות אינטרנט היא להציג תמונות באיכות הטובה ביותר בצורה היעילה ביותר. במאמר הזה נסביר על כמה שיטות שימושיות שאפשר להשתמש בהן כבר היום ובעתיד הקרוב.
אם אפשר, הימנעו משימוש בתמונות
לפני שפותחים את תיבת הדובים הזו, חשוב לזכור שיש באינטרנט הרבה טכנולוגיות חזקות שאינן תלויות ברזולוציה וב-DPI. באופן ספציפי, טקסט, קובצי SVG וחלק גדול מ-CSS פשוט יפעלו בגלל התכונה האוטומטית של שינוי הגודל לפי פיקסלים באינטרנט (באמצעות devicePixelRatio).
עם זאת, לא תמיד אפשר להימנע משימוש בתמונות רסטר. לדוגמה, יכול להיות שתקבלו נכסים שקשה מאוד לשחזר ב-SVG/CSS טהור, או שאתם עובדים עם תמונה. אפשר להמיר את התמונה ל-SVG באופן אוטומטי, אבל אין הרבה טעם להפוך תמונות לוקטוריות כי בדרך כלל גרסאות מוגדלות לא נראות טוב.
רקע
היסטוריה קצרה מאוד של צפיפות התצוגה
בימים הראשונים, צפיפות הפיקסלים במסכי המחשב הייתה 72 או 96dpi (נקודות לאינץ').
צפיפות הפיקסלים במסכים השתפרה בהדרגה, בעיקר בגלל תרחיש השימוש בניידים, שבו המשתמשים בדרך כלל מחזיקים את הטלפונים קרוב יותר לפניהם, כך שהפיקסלים גלויים יותר. עד שנת 2008, טלפונים ברזולוציה של 150dpi היו הנורמה החדשה. המגמה של צפיפות תצוגה גבוהה יותר נמשכה, והטלפונים החדשים של היום כוללים תצוגות של 300dpi (המותג של Apple הוא 'Retina').
כמובן, הפתרון האידיאלי הוא מסך שבו הפיקסלים לא נראים בכלל. מבחינת גורם הצורה של הטלפון, יכול להיות שהדור הנוכחי של מסכי Retina/HiDPI קרוב לאידיאל הזה. עם זאת, סוגים חדשים של חומרה ואביזרים לבישים כמו Project Glass צפויים להמשיך להגדיל את צפיפות הפיקסלים.
בפועל, תמונות בצפיפות נמוכה אמורות להיראות זהות במסכים חדשים כמו במסכים ישנים, אבל בהשוואה לתמונות החדות בצפיפות גבוהה שהמשתמשים רגילים לראות, התמונות בצפיפות נמוכה נראות מטושטשות ומקובצות. בהמשך מוצגת הדמיה גסה של איך תמונה בגודל 1x תיראה במסך בגודל 2x. לעומת זאת, התמונה ברזולוציה כפולה נראית טובה למדי.


פיקסלים באינטרנט
כשהאינטרנט תוכנן, 99% מהמסכים היו ברזולוציה של 96dpi (או התחזו לכך), ונעשה מעט מאוד כדי להתאים את האינטרנט למגוון רזולוציות. בגלל השונות הרבה בגדלים ובדחיסות של המסכים, נזקקנו לדרך סטנדרטית שתעזור לתמונות להיראות טוב במגוון דחיסות ומימדים של מסכים.
מפרט ה-HTML טיפל בבעיה הזו לאחרונה על ידי הגדרת פיקסל עזר שבעזרתו היצרנים יכולים לקבוע את הגודל של פיקסל CSS.
בעזרת פיקסל העזר, היצרן יכול לקבוע את הגודל של הפיקסל הפיזי של המכשיר ביחס לפיקסל הסטנדרטי או האידיאלי. היחס הזה נקרא 'יחס הפיקסלים של המכשיר'.
חישוב יחס הפיקסלים של המכשיר
נניח לטלפון חכם יש מסך עם גודל פיקסלים פיזי של 180 פיקסלים לאינץ' (ppi). כדי לחשב את יחס הפיקסלים של המכשיר, צריך לבצע שלושה שלבים:
משווים בין המרחק בפועל שבו המכשיר מוחזק למרחק של פיקסל העזר.
לפי המפרט, אנחנו יודעים שבמסך בגודל 28 אינץ', הרזולוציה האידיאלית היא 96 פיקסלים לאינץ'. עם זאת, מכיוון שמדובר בסמארטפון, אנשים מחזיקים את המכשיר קרוב יותר לפניהם מאשר מחשב נייד. נניח שהמרחק הוא 45 ס"מ.
כדי לקבל את צפיפות הפיקסלים האידיאלית למרחק הנתון, צריך להכפיל את יחס המרחק בצפיפות הרגילה (96ppi).
idealPixelDensity = (28/18) * 96 = 150 פיקסלים לאינץ' (כמעט)
כדי לקבל את יחס הפיקסלים של המכשיר, מחלקים את צפיפות הפיקסלים הפיזית בצפיפות הפיקסלים האידיאלית.
devicePixelRatio
= 180/150 = 1.2

עכשיו, כשהדפדפן צריך לדעת איך לשנות את גודל התמונה כך שתתאים למסך לפי הרזולוציה האידיאלית או הרגילה, הוא מתייחס ליחס הפיקסלים של המכשיר, שהוא 1.2 – כלומר, לכל פיקסל אידיאלי יש במכשיר הזה 1.2 פיקסלים פיזיים. הנוסחה לחישוב הפיקסלים האידיאליים (כפי שמוגדרים במפרט האינטרנט) והפיקסלים הפיזיים (הנקודות במסך המכשיר) היא:
physicalPixels = window.devicePixelRatio * idealPixels
בעבר, ספקי מכשירים נטו לעגל את הערכים של devicePixelRatios
(DPR). ב-iPhone וב-iPad של Apple מדווחים על צפיפות פיקסלים של 1, ובמכשירים המקבילים עם מסך Retina מדווחים על צפיפות פיקסלים של 2. במפרט CSS מומלץ
יחידת הפיקסלים מתייחסת למספר השלם של פיקסלים במכשיר שהכי קרוב לפיקסל העזר.
אחת הסיבות לכך שיחסי גובה-רוחב עגולים יכולים להיות טובים יותר היא שהם עשויים להוביל לפחות פגמים ברמת הפיקסל המשני.
עם זאת, המציאות של מגוון המכשירים הרבה יותר מגוונת, ולרוב לטלפונים עם Android יש שיעור המרה של 1.5. הטאבלט Nexus 7 כולל DPR של כ-1.33, שחושב לפי חישוב דומה לזה שלמעלה. בעתיד נוסיף עוד מכשירים עם שיעורי הכנסה משתנים. לכן, לעולם אל תניחו שללקוחות שלכם יהיו ערכי DPR שלמים.
סקירה כללית של טכניקות לתמונות HiDPI
יש הרבה שיטות לפתרון הבעיה של הצגת התמונות באיכות הטובה ביותר במהירות האפשרית, והן נחלקות לשתי קטגוריות עיקריות:
- אופטימיזציה של תמונות בודדות, וגם
- אופטימיזציה של הבחירה בין כמה תמונות.
גישות של תמונה אחת: משתמשים בתמונה אחת, אבל עושים איתה משהו חכם. החיסרון של הגישות האלה הוא שאי אפשר להימנע מהתפשרות בביצועים, כי תצטרכו להוריד תמונות HiDPI גם במכשירים ישנים יותר עם DPI נמוך יותר. ריכזנו כאן כמה גישות למקרה של תמונה אחת:
- תמונה דחוסה מאוד באיכות HiDPI
- פורמט תמונה נהדר
- פורמט תמונה הדרגתי
גישות של כמה תמונות: משתמשים בכמה תמונות, אבל בוחרים באחת מהן באופן חכם. לגישה הזו יש עלות תפעולית מובנית, כי המפתח צריך ליצור כמה גרסאות של אותו נכס ואז להחליט איזו גרסה להשתמש בה. האפשרויות העומדות לרשותך הן:
- JavaScript
- העברה בצד השרת
- שאילתות מדיה של CSS
- תכונות מובנות בדפדפן (
image-set()
,<img srcset>
)
תמונה דחוסה מאוד באיכות HiDPI
תמונות כבר מהוות 60% מרוחב הפס שמשמש להורדת אתר ממוצע. הצגת תמונות HiDPI לכל הלקוחות תגדיל את המספר הזה. עד כמה הוא יגדל?
הרצתי כמה בדיקות שיצרו קטעי תמונה בגודל 1x ו-2x באיכות JPEG של 90, 50 ו-20. זהו סקריפט המעטפת שהשתמשתי בו (באמצעות ImageMagick) כדי ליצור אותם:



מהמדגם הקטן והלא מדעי הזה, נראה שאפשר לדחוס תמונות גדולות בלי להתפשר על האיכות. לדעתי, תמונות ברזולוציה כפולה שדחוסות מאוד נראות טוב יותר מאשר תמונות ברזולוציה רגילה שלא דחוסות.
כמובן, הצגת תמונות באיכות נמוכה ודחוסה מאוד בגודל 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 מאחור, אבל עדיין מדובר בשיפור מצטבר יחסית – הגודל של קובצי WebP קטן ב-30% בערך, על סמך הגלריה הזו של WebP. לכן, WebP לבדו לא מספיק כדי לטפל בבעיה של DPI גבוה.
פורמטים של תמונות פרוגרסיביות
לפורמטים של תמונות פרוגרסיביות כמו 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
יופעל. מידע נוסף זמין במאמר של Jason Grigsby.
בחירת התמונה שתישאר בשרת
כדי לדחות את ההחלטה לצד השרת, אפשר לכתוב טיפולי בקשות מותאמים אישית לכל תמונה שאתם מציגים. בורר כזה יבדוק אם יש תמיכה ב-Retina על סמך User-Agent (החלק היחיד של המידע שמוענק לשרת). לאחר מכן, בהתאם ללוגיקת הצד הלקוח שרוצה להציג נכסי HiDPI, אפשר לטעון את הנכס המתאים (שנקרא לפי מוסכמה מוכרת כלשהי).
לצערנו, ה-User-Agent לא תמיד מספק מספיק מידע כדי לקבוע אם צריך לשלוח למכשיר תמונות באיכות גבוהה או נמוכה. כמו כן, מובן מאליו שכל מה שקשור ל-User-Agent הוא פריצה, ויש להימנע ממנו אם אפשר.
שימוש בשאילתות מדיה של 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
);
המשמעות של הקוד הזה היא שיש שתי תמונות לבחירה. אחד מהם מותאם למסכים ברזולוציה רגילה, והשני למסכים ברזולוציה כפולה. לאחר מכן הדפדפן בוחר איזו גרסה לטעון, על סמך מגוון גורמים, שיכולים לכלול גם את מהירות הרשת, אם הדפדפן מספיק חכם (לפי מה שידוע לי, זה לא מיושם כרגע).
בנוסף לטעינת התמונה הנכונה, הדפדפן גם יתאים את התמונה למסך. במילים אחרות, הדפדפן מניח ששתי תמונות גדולות פי שניים מתמונה אחת, ולכן הוא יאפס את התמונה עם שתי הרזולוציות ביחס של פי שניים, כך שהתמונה תופיע באותו גודל בדף.
במקום לציין 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 בכל שאר המכשירים.
שימוש ב-image-set לרכיבי תמונה
מאחר שמאפיין 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
עדיין חלקית, אבל יש חלופות סבירות שאפשר להשתמש בהן כבר היום.
לסיכום, ההמלצות שלי הן:
- לתמונות רקע, השתמשו ב-image-set עם החלופות המתאימות לדפדפנים שלא תומכים בו.
- בתמונות תוכן, צריך להשתמש ב-srcset polyfill או לעבור ל-שימוש ב-image-set (כפי שמתואר למעלה).
- במצבים שבהם אתם מוכנים להתפשר על איכות התמונה, כדאי להשתמש בתמונות דחוסות מאוד בגודל 2x.