صور عالية لكل بوصة (DPI) لكثافة وحدات البكسل المتغيّرة

تتمثل إحدى ميزات النظام المعقد حاليًا للأجهزة في توفّر مجموعة كبيرة جدًا من كثافات وحدات بكسل الشاشة. تتميز بعض الأجهزة بشاشات عالية الدقة للغاية، في حين أن أجهزة أخرى تتخلف عن الخلف. يحتاج مطورو التطبيقات إلى دعم مجموعة من كثافات البكسل، والتي قد تمثل تحديًا كبيرًا. تتفاقم التحديات على ويب الهاتف المحمول بعدة عوامل:

  • مجموعة كبيرة من الأجهزة ذات أشكال الأجهزة المختلفة.
  • النطاق الترددي للشبكة وعمر البطارية محدودان.

ومن حيث الصور، إنّ الهدف من مطوّري تطبيقات الويب هو عرض أفضل الصور ذات الجودة بأكبر قدر ممكن من الكفاءة. ستتناول هذه المقالة بعض الأساليب المفيدة للقيام بذلك اليوم وفي المستقبل القريب.

تجنب الصور إن أمكن

قبل فتح هذه العلبة الخاصة بالفيروسات المتنقلة، تذكّر أنّ الويب يتضمّن العديد من التقنيات الفعّالة التي لا تعتمد على الدقة وعدد النقاط لكل بوصة (DPI). وعلى وجه التحديد، "يمكن" استخدام النص وSVG والعديد من صفحات CSS بشكل "فعّال" بسبب ميزة تحجيم وحدات البكسل التلقائية على الويب (عبر devicePixelRatio).

ومع ذلك، لا يمكنك دائمًا تجنب الصور النقطية. على سبيل المثال، قد تظهر لك أصول يصعب نسخها إلى SVG/CSS فقط، أو أنك تتعامل مع صورة فوتوغرافية. في حين أنه يمكنك تحويل الصورة إلى SVG تلقائيًا، فإن الصور المتجهة ليس لها معنى لأن الصور التي يتم تكبيرها لا تبدو عادةً جيدة.

الخلفية

سجلّ قصير جدًا عن كثافة العرض

في بداياتنا، كانت كثافة وحدات البكسل في شاشات الكمبيوتر 72 أو 96 نقطة لكل بوصة (نقطة لكل بوصة).

تحسّنت كثافة وحدات البكسل تدريجيًا، ويستند ذلك إلى حد كبير من حالة استخدام الهاتف الجوّال، والتي يقرّب فيها المستخدمون هواتفهم بشكل عام من الوجوه، ما يجعل وحدات البكسل مرئية أكثر. بحلول عام 2008، أصبحت الهواتف التي تبلغ دقتها 150 نقطة لكل بوصة المعيار الجديد. استمر الاتجاه في زيادة كثافة العرض باستمرار، وتتضمن الهواتف الجديدة اليوم شاشات تبلغ درجة دقتها 300 نقطة لكل بوصة (تحمل العلامة التجارية "Retina" من Apple).

الكأس المقدسة، بالطبع، هي شاشة تكون فيها وحدات البكسل غير مرئية تمامًا. بالنسبة لعامل شكل الهاتف، فإن الجيل الحالي من شاشات Retina/HiDPI قد يكون قريبًا من المستوى المثالي. ولكن من المحتمل أن تستمر فئات جديدة من الأجهزة والأجهزة القابلة للارتداء مثل Project Glass في زيادة كثافة وحدات البكسل.

من الناحية العملية، يُفترض أن تبدو الصور منخفضة الكثافة بالشكل نفسه على الشاشات الجديدة كما كانت على الشاشات القديمة، ولكن بالمقارنة مع الصور الواضحة التي اعتاد المستخدمون على رؤيتها، تبدو الصور منخفضة الكثافة مزعجة ومتقطّعة. فيما يلي محاكاة تقريبية لكيفية ظهور صورة 1x على شاشة 2x. في المقابل، تبدو الصورة 2x جيدة جدًا.

بابون 1x
بابون 2x
قردة البابون: بكثافة مختلفة لوحدات البكسل.

وحدات البكسل على الويب

عندما تم تصميم الويب، كانت نسبة 99% من الشاشات تظهر 96 نقطة لكل بوصة (أو تظاهر بأنّها)، وقد تم وضع عدد قليل من الشروط على مستوى التباين في هذه الواجهة. بسبب الاختلاف الكبير في أحجام الشاشات وكثافاتها، نحتاج إلى طريقة معيارية لجعل الصور تبدو جيدة عبر مجموعة متنوعة من كثافات الشاشات وأبعادها.

عالجت مواصفات HTML هذه المشكلة مؤخرًا من خلال تحديد وحدة بكسل مرجعية تستخدمها الشركات المصنّعة لتحديد حجم بكسل CSS.

وباستخدام وحدة البكسل المرجعية، يمكن للشركة المصنعة تحديد حجم البكسل الفعلي للجهاز بالنسبة إلى البكسل القياسي أو المثالي. وتُسمى هذه النسبة نسبة وحدات البكسل في الجهاز.

جارٍ حساب نسبة وحدات البكسل في الجهاز

لنفترض أن هناك هاتفًا ذكيًا يحتوي على شاشة بحجم بكسل فعلي يبلغ 180 بكسل لكل بوصة (ppi). يتطلب حساب نسبة وحدات البكسل للجهاز ثلاث خطوات:

  1. مقارنة المسافة الفعلية التي يمسك بها الجهاز بالمسافة للبكسل المرجعي.

    وفقًا للمواصفات، نعلم أنه عند ارتفاع 28 بوصة، يكون الحجم المثالي 96 بكسل لكل بوصة. ومع ذلك، بما أنّه هاتف ذكي، يقر الأشخاص الجهاز بالقرب من وجوههم أكثر من حمل الكمبيوتر المحمول. لنقدر تلك المسافة بحيث تكون 18 بوصة.

  2. اضرب نسبة المسافة بالكثافة العادية (96 بكسل في البوصة) للحصول على الكثافة المثالية لوحدات البكسل للمسافة المحدّدة.

    examplePixelDensity = (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 بها دقّة مستدامة تبلغ 1.5. يحتوي الجهاز اللوحي Nexus 7 على معدل نسخ نقدي واحد (DPR) يبلغ 1.33 تقريبًا، وقد تم الوصول إليه عن طريق عملية حسابية مشابهة لتلك الموضحة أعلاه. ومن المتوقّع أن تظهر في المستقبل المزيد من الأجهزة التي تتضمّن بيانات متغيرة لمعدلات النسخ الاحتياطي. لهذا السبب، يجب ألا تفترض أبدًا أنّ عملائك سيحصلون على عدد صحيح من أخطاء DPR.

نظرة عامة على تقنيات صورة HiDPI

هناك العديد من الأساليب التي يمكن من خلالها حل مشكلة عرض الصور ذات الجودة الأفضل في أسرع وقت ممكن، وتندرج على نطاق واسع ضمن فئتين:

  1. يعد تحسين الصور الفردية
  2. تحسين الاختيار بين صور متعددة.

تقارب صورة واحدة: استخدام صورة واحدة، لكن افعل شيئًا ذكيًا معه. وهذه الأساليب لها عيب أنها ستضحي حتمًا بالأداء، حيث إنك ستنزّل صور HiDPI حتى على الأجهزة القديمة التي تكون فيها عدد النقاط لكل بوصة أقل. في ما يلي بعض الأساليب لحالة الصورة الواحدة:

  • صورة HiDPI مضغوطة بدرجة كبيرة
  • تنسيق صورة رائع للغاية
  • تنسيق الصورة التقدمية

مناهج متعددة للصور: استخدام صور متعددة، لكن عليك اتخاذ إجراء ذكي لاختيار الصور التي سيتم تحميلها لهذه المناهج أعباء عامة مرتبطة بالمطور لإنشاء إصدارات متعددة من نفس مادة العرض ثم تحديد استراتيجية اتخاذ القرار. في ما يلي الخيارات المتاحة:

  • JavaScript
  • التسليم من جهة الخادم
  • الاستعلامات عن وسائط CSS
  • ميزات المتصفّح المضمَّنة (image-set()، <img srcset>)

صورة HiDPI مضغوطة بدرجة كبيرة

إنّ الصور تستهلك حاليًا نسبة 60% من معدل نقل البيانات في تنزيل أي موقع إلكتروني عادي. من خلال عرض صور HiDPI لجميع العملاء، سنزيد هذا العدد. ما مقدار الزيادة التي ستنمو؟

لقد أجريت بعض الاختبارات التي أدّت إلى إنشاء أجزاء صور 1x و2x بجودة JPEG عند 90 و50 و20. إليك نص شيلي الذي استخدمته (استخدام ImageMagick) لإنشائها:

مثال 1 على المربّعات. المثال 2 للمربّعات. مثال 3 على المربّعات.
عيّنات من الصور بضغطات مختلفة وكثافات وحدات بكسل.

ومن هذه العينات الصغيرة غير العلمية، يبدو أن ضغط الصور الكبيرة يوفر مقايضة جيدة بين الحجم والجودة. بالنسبة لعيني، تبدو الصور المضغوطة بشكل كبير مرتين في الواقع أفضل من الصور 1x غير المضغوطة.

لا شكّ في أنّ عرض صور ذات جودة منخفضة وبحجم 2x على أجهزة ذات جودة أعلى يكون أسوأ من عرض صور ذات جودة أعلى، ويؤدي النهج السابق إلى فرض عقوبات على جودة الصور. إذا قارنت الجودة: 90 صورة بالجودة: 20 صورة، ستلاحظ انخفاضًا في الوضوح وزيادة الحبيبات. وقد لا تكون هذه العناصر مقبولة في الحالات التي تكون فيها الصور العالية الجودة أمرًا أساسيًا (على سبيل المثال، تطبيق عارض الصور)، أو بالنسبة إلى مطوّري التطبيقات الذين لا يريدون تقديم حل وسط.

تم إجراء المقارنة أعلاه بالكامل باستخدام ملفات JPEG المضغوطة. تجدُر الإشارة إلى أنّ هناك العديد من المفاضلات بين تنسيقات الصور التي يتمّ تنفيذها على نطاق واسع (JPEG وPNG وGIF)، ما يتيح لنا إجراء ما يلي:

تنسيق صورة رائع للغاية

تنسيق WebP هو تنسيق صور مقنع يتم ضغطه بشكل جيد جدًا مع الحفاظ على دقة عالية للصورة. بالطبع، لم يتم تطبيقها في كل مكان حتى الآن!

وإحدى الطرق المتاحة هي التأكّد من توفُّر محتوى WebP عن طريق JavaScript. عليك تحميل صورة بحجم 1 بكسل عبر data-uri، والانتظار إلى حين تنشيط أحداث التحميل أو الخطأ، ثم التحقق من صحة الحجم. تتوفّر Modernizr مع نص برمجي لرصد الميزات هذا وهو متاح من خلال Modernizr.webp.

مع ذلك، تتوفّر طريقة أفضل للقيام بذلك في CSS مباشرةً باستخدام دالةimage(). لذا، إذا كان لديك صورة WebP واحتياطي JPEG، يمكنك كتابة ما يلي:

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

هناك بعض المشكلات في هذا النهج. أولاً، لم يتم تنفيذ image() على الإطلاق على نطاق واسع. ثانيًا، على الرغم من أنّ ضغط WebP يُضخِّ محتوى JPEG خارج الماء، لا يزال يتم تحسينه بشكل تدريجي نسبيًا، أي أنّ حجمه أصغر بنسبة% 30 تقريبًا استنادًا إلى معرض WebP هذا. وبالتالي، لا يكفي تنسيق WebP وحده لمعالجة مشكلة ارتفاع عدد النقاط لكل بوصة.

تنسيقات الصور التقدّمية

تتمتع تنسيقات الصور التقدمية، مثل JPEG 2000 وProgressive JPEG وProgressive وPNG وGIF، بفائدة (التي تمت مناقشتها إلى حد ما) تتمثل في ظهور الصورة قبل تحميلها بالكامل. قد تتحمّل بعض النفقات العامة، على الرغم من وجود أدلة متضاربة على ذلك. ادّعى "جيف أتوود" أنّ الوضع التدريجي "يضيف نسبة% 20 تقريبًا إلى حجم صور PNG وحوالي% 10 إلى حجم صور JPEG وGIF". ومع ذلك، ادّعى "ستويان ستيفانوف" أنّه بالنسبة إلى الملفات الكبيرة، يكون الوضع التقدّمي أكثر كفاءة (في معظم الحالات).

للوهلة الأولى، تبدو الصور التقدّمية واعدةً للغاية في سياق عرض أفضل الصور ذات الجودة في أسرع وقت ممكن. والفكرة هي أنه يمكن للمتصفح التوقف عن تنزيل صورة وفك ترميزها بمجرد معرفة أن البيانات الإضافية لن تزيد من جودة الصورة (أي أن جميع تحسينات الدقة هي وحدات بكسل فرعية).

على الرغم من سهولة إنهاء الاتصالات، إلا أن إعادة تشغيلها غالبًا ما تكون مكلفة. بالنسبة إلى المواقع الإلكترونية التي تحتوي على العديد من الصور، يكون المنهج الأكثر فعالية هو الحفاظ على اتصال HTTP واحد، وإعادة استخدامه لأطول فترة ممكنة. إذا تم إنهاء الاتصال بشكل مبكر بسبب تنزيل صورة واحدة بما يكفي، سيحتاج المتصفّح إلى إنشاء اتصال جديد، والذي يمكن أن يكون بطيء في البيئات ذات وقت الاستجابة المنخفض.

وكحلّ بديل، يمكنك استخدام طلب نطاق HTTP، الذي يسمح للمتصفّحات بتحديد نطاق من وحدات البايت لجلبها. بإمكان المتصفح الذكي إنشاء طلب head ومعالجته وتحديد الكمية المطلوبة من الصورة ثم جلبه. للأسف، يتم دعم نطاق HTTP بشكل سيئ في خوادم الويب، ما يجعل هذا الأسلوب غير عملي.

وأخيرًا، يتمثل القيد الواضح لهذا النهج في أنه لا يمكنك اختيار الصورة التي تريد تحميلها، وإنما درجات الدقة المختلفة فقط للصورة نفسها. نتيجةً لذلك، لا يعالج هذا العمود حالة الاستخدام "اتجاه الرسومات".

استخدام JavaScript لتحديد الصورة التي تريد تحميلها

الطريقة الأولى والأكثر وضوحًا لتحديد الصورة التي سيتم تحميلها هي استخدام JavaScript في البرنامج. يتيح لك هذا النهج معرفة كل شيء عن وكيل المستخدم والقيام بالشيء الصحيح. ويمكنك تحديد نسبة وحدات البكسل على الجهاز من خلال window.devicePixelRatio، والحصول على عرض الشاشة وارتفاعها، وربما إجراء بعض عمليات رصد الاتصال بالشبكة عبر navigator.connection أو إصدار طلب وهمي، كما هو الحال في مكتبة foresight.js. بمجرد أن تجمع كل هذه المعلومات، يمكنك تحديد الصورة المراد تحميلها.

وهناك ما يقرب من مليون مكتبة JavaScript تقوم بشيء مثل ما ورد أعلاه، لكن للأسف أي منها ليس ذا قيمة خاصة.

من العيوب الكبيرة في هذه الطريقة أنّ استخدام JavaScript يعني أنّه سيؤخّر تحميل الصورة إلى أن ينتهي محلّل النظر إلى الأمام. وهذا يعني أنّ تنزيل الصور لن يبدأ إلا بعد تنشيط حدث pageload. يمكنك الاطّلاع على مزيد من المعلومات حول هذا الموضوع في مقالة "جايسون غريغبي".

تحديد الصورة المراد تحميلها على الخادم

يمكنك تأجيل القرار إلى جانب الخادم عن طريق كتابة معالجات طلبات مخصصة لكل صورة تعرضها. ويتحقق هذا المعالج من دعم Retina بناءً على وكيل المستخدم (وهو المعلومة الوحيدة التي يتم نقلها إلى الخادم). وبعد ذلك، واستنادًا إلى ما إذا كان منطق الخادم يريد خدمة أصول HiDPI، يمكنك تحميل مادة العرض المناسبة (التي تم تسميتها وفقًا لبعض الاصطلاحات المعروفة).

للأسف، لا يوفّر وكيل المستخدم بالضرورة معلومات كافية لتحديد ما إذا كان يجب أن يتلقّى الجهاز صورًا ذات جودة عالية أم منخفضة. علاوة على ذلك، نجد أن أي شيء متعلق بوكيل المستخدم هو أمر اختراق ويجب تجنُّبه إن أمكن.

استخدام الاستعلامات عن الوسائط في 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. كما تكتسب مرونة في اختيار نقاط التوقف سريعة الاستجابة (على سبيل المثال، يمكن أن يكون لديك صور نقاط لكل بوصة منخفضة ومتوسطة ومرتفعة)، والتي فُقدت مع أسلوب الخادم.

للأسف، لا يزال الأمر صعبًا بعض الشيء ويؤدي إلى ظهور CSS غريب (أو يتطلّب معالجة مسبقة). وتقتصر هذه الطريقة أيضًا على خصائص CSS، لذلك لا يمكن ضبط <img src>، ويجب أن تكون جميع صورك عناصر ذات خلفية. أخيرًا، من خلال الاعتماد الصارم على نسبة وحدات البكسل في الجهاز، قد ينتهي بك الأمر في بعض الحالات التي ينتهي فيها الأمر بتنزيل مادة عرض صورة ضخمة بحجم 2x على هاتفك الذكي الذي يتميز بنقاط عالية لكل بوصة أثناء استخدام اتصال EDGE. هذه ليست أفضل تجربة مستخدم.

استخدام ميزات المتصفّح الجديدة

كان هناك الكثير من المناقشات مؤخرًا حول دعم منصة الويب لمشكلة صورة DPI العالية. اقتحِت شركة Apple مؤخرًا هذه المساحة، وأضافت دالة CSS image-set() إلى WebKit. ونتيجة لذلك، يدعمه كل من Safari وChrome. وبما أنّها دالة CSS، لن يعالج image-set() مشكلة علامات <img>. أدخِل @srcset، الذي يعالج هذه المشكلة ولكن (في وقت كتابة هذا النص) لا يتوفر له أي عمليات تنفيذ مرجعية (حتى الآن). يتعمق القسم التالي في image-set وsrcset.

ميزات المتصفّح التي توفّر إمكانية استخدام عدد كبير من النقاط لكل بوصة

في النهاية، يعتمد القرار بشأن النهج الذي تتبعه على متطلباتك الخاصة. ومع ذلك، ضع في اعتبارك أن جميع المناهج المذكورة أعلاه لها عيوب. ومع ذلك، بالنظر إلى المستقبل، بعد حصول 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، بينما يتناسب الآخر مع 2x. يستطيع المتصفح بعد ذلك اختيار الإضافة التي سيتم تحميلها، بناءً على عدة عوامل، والتي قد تشمل سرعة الشبكة، إذا كان المتصفح ذكيًا بما يكفي (لم يتم تنفيذه حاليًا على حد علمي).

وبالإضافة إلى تحميل الصورة الصحيحة، سيعمل المتصفح أيضًا على ضبطها. بمعنى آخر، يفترض المتصفح أنّ حجم صورتين مضاعفة حجم الصورة 1x، وبالتالي سيتم تصغير حجم الصورة 2x بضربة 2، بحيث تبدو الصورة بنفس الحجم على الصفحة.

بدلاً من تحديد 1x أو 1.5x أو Nx، يمكنك أيضًا تحديد كثافة وحدات بكسل معينة للجهاز بنقطة لكل بوصة.

يعمل هذا الإجراء بشكل جيد، باستثناء المتصفّحات التي لا تتوافق مع السمة 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 (أي إنشاء واجهة JavaScript من أجل) image-set() وإطلاقها يوميًا؟ كما اتضح، من الصعب جدًا تنفيذ رموز polyfill فعّالة لدوال 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 بكسل، وBanner-phone-HD.jpeg، إلى أجهزة DPI للشاشات الصغيرة ذات الشاشات الصغيرة العالية، وbanner-HD.jpeg إلى أجهزة DPI العالية التي تحتوي على شاشات أكبر من 640 بكسل، و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.

ملء srcset

من الميزات المفيدة في srcset أنّه مزوّد بعنصر احتياطي طبيعي. في حال عدم تنفيذ سمة srcset، تعرف جميع المتصفحات أنها تعالج سمة src. ونظرًا إلى أنّ هذه السمة مجرّد سمة HTML، من الممكن إنشاء رموز polyfill باستخدام JavaScript.

يتضمّن رمز polyfill هذا اختبارات الوحدات للتأكّد من أنّه أقرب ما يمكن للمواصفات. بالإضافة إلى ذلك، هناك عمليات تحقّق تمنع polyfill من تنفيذ أي رموز برمجية إذا تم تنفيذ srcset في الأصل.

إليك عرضًا توضيحيًا لرموز polyfill وهي تظهر بشكل عملي.

الخلاصة

ليس هناك نقطة سحرية لحل مشكلة صور النقاط العالية لكل بوصة.

الحل الأسهل هو تجنّب الصور كليًا، واختيار الرسومات الموجّهة التي يمكن تغيير حجمها (SVG) وCSS بدلاً من ذلك. ومع ذلك، هذا ليس واقعيًا دائمًا، خاصةً إذا كانت لديك صور عالية الجودة على موقعك.

تتميز جميع المناهج في JavaScript وCSS واستخدام جانب الخادم بنقاط القوة والضعف فيها. مع ذلك، فإنّ النهج الواعد لذلك هو الاستفادة من ميزات المتصفّح الجديدة. على الرغم من أنّ التوافق مع image-set وsrcset ما زال غير مكتمل، تتوفّر عناصر احتياطية معقولة لاستخدامها في الوقت الحالي.

في ما يلي ملخّص للاقتراحات:

  • بالنسبة إلى صور الخلفية، استخدِم السمة image-set مع العناصر الاحتياطية المناسبة للمتصفّحات غير المتوافقة.
  • بالنسبة إلى صور المحتوى، استخدِم srcset polyfill أو استخدِم العنصر الاحتياطي استخدام image-set (انظر أعلاه).
  • بالنسبة إلى الحالات التي تريد فيها التضحية بجودة الصورة، ننصحك باستخدام صور 2x مضغوطة بكثافة.