نهج غير سريع الاستجابة لإنشاء تطبيقات ويب متوافقة مع جميع الأجهزة

الاستعلامات عن الوسائط رائعة، ولكن…

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

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

  • تحصل جميع الأجهزة على ملفات JavaScript وCSS والأصول (الصور والفيديوهات) نفسها، ما يؤدي إلى أوقات تحميل أطول من اللازم.
  • تحصل جميع الأجهزة على نموذج DOM الأوّلي نفسه، ما قد يضطر المطوّرين إلى كتابة CSS معقّدة بشكل مفرط.
  • مرونة محدودة لتحديد تفاعلات مخصّصة مصمّمة خصيصًا لكل جهاز.

تتطلّب تطبيقات الويب أكثر من طلبات البحث عن الوسائط

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

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

ما هي فئات الأجهزة التي تستهدفها؟

هناك الكثير من الأجهزة المتصلة بالإنترنت، ومعظمها مزوّد بمتصفحات. تكمن المشكلة في تنوّعها، إذ تشمل أجهزة كمبيوتر Mac المحمولة ومحطات عمل Windows وأجهزة iPhone وiPad وهواتف Android التي تعمل باللمس وعجلات التمرير ولوحات المفاتيح والإدخال الصوتي والأجهزة التي تستجيب للضغط والساعات الذكية والمحامص والثلاجات وغيرها الكثير. بعض هذه الأجهزة منتشرة في كل مكان، في حين أنّ البعض الآخر نادر جدًا.

مجموعة متنوعة من الأجهزة
مجموعة متنوعة من الأجهزة (المصدر).

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

هناك طرفان متناقضان في طيف أساليب التقييم:

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

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

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

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

حلّ محتمل

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

  1. الشاشات الصغيرة + اللمس (الهواتف في الغالب)
  2. الشاشات الكبيرة + اللمس (معظمها أجهزة لوحية)
  3. الشاشات الكبيرة + لوحة المفاتيح/الماوس (معظمها أجهزة كمبيوتر مكتبية/محمولة)

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

أمثلة على تطبيقات الويب الخاصة بشكل الجهاز

هناك العديد من الأمثلة على المواقع الإلكترونية التي تعرض إصدارات مختلفة تمامًا لأشكال الأجهزة المختلفة. يحدث ذلك في "بحث Google" وفي Facebook. وتشمل الاعتبارات المتعلقة بذلك الأداء (استرداد مواد العرض وعرض الصفحات) وتجربة المستخدم بشكل عام.

في عالم التطبيقات الأصلية، يختار العديد من المطوّرين تخصيص تجربة التطبيق حسب فئة الجهاز. على سبيل المثال، تختلف واجهة مستخدم تطبيق Flipboard على iPad عن واجهة مستخدم التطبيق على iPhone. تم تحسين إصدار الجهاز اللوحي لاستخدامه باليدين مع إمكانية قلب الشاشة أفقيًا، بينما تم تصميم إصدار الهاتف للتفاعل بيد واحدة مع إمكانية قلب الشاشة عموديًا. توفّر العديد من تطبيقات iOS الأخرى أيضًا إصدارات مختلفة بشكل كبير للهواتف والأجهزة اللوحية، مثل Things (قائمة المهام) وShowyou (الفيديوهات الاجتماعية)، كما هو موضّح أدناه:

تخصيص كبير لواجهة المستخدم على الهواتف والأجهزة اللوحية
تخصيص كبير لواجهة المستخدم على الهواتف والأجهزة اللوحية:

الطريقة 1: رصد الأخطاء من جهة الخادم

على الخادم، لدينا فهم محدود جدًا للجهاز الذي نتعامل معه. ربما تكون المعلومة الأكثر فائدة المتاحة هي سلسلة وكيل المستخدم، والتي يتم توفيرها من خلال عنوان User-Agent في كل طلب. لهذا السبب، سينجح هنا النهج نفسه الذي يتّبعه UA في رصد التطبيقات. في الواقع، يتيح مشروعا DeviceAtlas وWURFL ذلك حاليًا (ويوفّران الكثير من المعلومات الإضافية حول الجهاز).

ولكن كلّ منها يطرح تحدياته الخاصة. إنّ WURFL كبير جدًا، إذ يحتوي على 20 ميغابايت من XML، ما قد يؤدي إلى تكبّد نفقات كبيرة على مستوى الخادم لكل طلب. هناك مشاريع تقسم ملف XML لأسباب تتعلق بالأداء. ‫DeviceAtlas ليست مفتوحة المصدر، ويتطلّب استخدامها الحصول على ترخيص مدفوع.

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

الطريقة 2: الرصد من جهة العميل

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

علينا وضع حد فاصل في مكان ما للتمييز بين الأجهزة الصغيرة والكبيرة التي تعمل باللمس. ماذا عن الحالات الحدّية، مثل هاتف Galaxy Note بشاشة 5 بوصة؟ يعرض الرسم البياني التالي مجموعة من أجهزة Android وiOS الشائعة التي تم تراكبها (مع درجات دقة الشاشة المقابلة). تشير علامة النجمة إلى أنّ الجهاز يتوفّر أو يمكن أن يتوفّر بكثافة مضاعفة. على الرغم من أنّ كثافة البكسل قد تتضاعف، إلا أنّ CSS لا يزال يعرض الأحجام نفسها.

ملاحظة سريعة حول وحدات البكسل في CSS: وحدات البكسل في CSS على الويب على الأجهزة الجوّالة ليست هي نفسها وحدات البكسل على الشاشة. وقد أدخلت أجهزة iOS Retina ممارسة مضاعفة كثافة البكسل (على سبيل المثال، iPhone 3GS مقابل 4 وiPad 2 مقابل 3). لا تزال وكلاء المستخدمين في متصفّح Mobile Safari على شاشات Retina يعرضون عرض الجهاز نفسه لتجنُّب حدوث مشاكل في الويب. كما هو الحال مع الأجهزة الأخرى (مثل عندما تحصل أجهزة Android على شاشات بدقة أعلى، فإنّها تستخدم الحيلة نفسها المتعلقة بعرض الجهاز.

درجة دقة الجهاز (بالبكسل)
درجة دقة الجهاز (بالبكسل):

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

في المخطّط التالي، تمثّل المربّعات الحد الأقصى لأبعاد كل جهاز، وذلك نتيجة لتراكب المخطّطَين التفصيليَين للوضعَين العمودي والأفقي (وإكمال المربّع):

دقة الوضعين الرأسي والأفقي (بالبكسل)
دقّة الوضع العمودي والأفقي (بالبكسل)

من خلال ضبط الحدّ الأدنى على 650px، نصنّف هواتف iPhone وGalaxy Nexus على أنّها أجهزة صغيرة تعمل باللمس، وأجهزة iPad وGalaxy Tab على أنّها أجهزة لوحية. في هذه الحالة، يتم تصنيف جهاز Galaxy Note الذي يمكن استخدامه كجهاز لوحي أو هاتف على أنّه "هاتف"، وسيتم عرض تخطيط الهاتف عليه.

وبالتالي، قد تبدو الاستراتيجية المعقولة على النحو التالي:

if (hasTouch) {
  if (isSmall) {
    device = PHONE;
  } else {
    device = TABLET;
  }
} else {
  device = DESKTOP;
}

يمكنك الاطّلاع على عيّنة بسيطة من نهج رصد الميزات أثناء التنفيذ.

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

var ua = navigator.userAgent;
for (var re in RULES) {
  if (ua.match(re)) {
    device = RULES[re];
    return;
  }
}

يمكنك الاطّلاع على عيّنة من نهج رصد وكيل المستخدم أثناء العمل.

ملاحظة حول التحميل من جهة العميل

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

  1. إعادة التوجيه إلى عنوان URL خاص بنوع الجهاز يتضمّن إصدار هذا النوع من الأجهزة
  2. تحميل مواد العرض الخاصة بنوع الجهاز بشكل ديناميكي

الأسلوب الأول بسيط، ويتطلّب إعادة توجيه مثل window.location.href = '/tablet'. ومع ذلك، سيتم الآن إلحاق معلومات نوع الجهاز بالموقع الجغرافي، لذا ننصحك باستخدام History API لتنظيف عنوان URL. لسوء الحظ، يتضمّن هذا الأسلوب عملية إعادة توجيه قد تكون بطيئة، خاصةً على الأجهزة الجوّالة.

الأسلوب الثاني أكثر تعقيدًا بكثير من حيث التنفيذ. تحتاج إلى آلية لتحميل CSS وJS بشكل ديناميكي، وقد لا تتمكّن (حسب المتصفّح) من تنفيذ إجراءات مثل تخصيص <meta viewport>. بالإضافة إلى ذلك، بما أنّه لا تتم إعادة التوجيه، ستبقى عالقًا في صفحة HTML الأصلية التي تم عرضها. بالطبع، يمكنك تعديلها باستخدام JavaScript، ولكن قد يكون ذلك بطيئًا و/أو غير مناسب، وذلك حسب تطبيقك.

تحديد ما إذا كان الجهاز هو العميل أو الخادم

في ما يلي المفاضلة بين الطريقتَين:

عميل Pro:

  • أكثر ملاءمةً للمستقبل لأنّه يستند إلى أحجام الشاشات/إمكاناتها بدلاً من Universal Analytics.
  • لا حاجة إلى تعديل قائمة UA باستمرار.

خادم Pro:

  • التحكّم الكامل في الإصدار الذي سيتم عرضه على الأجهزة
  • أداء أفضل: لا حاجة إلى عمليات إعادة توجيه من جهة العميل أو التحميل الديناميكي.

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

نقدّم لك device.js

‫Device.js هي نقطة بداية لتنفيذ عملية رصد الأجهزة المستندة إلى الاستعلامات الدلالية والوسائط بدون الحاجة إلى إعدادات خاصة من جهة الخادم، ما يوفّر الوقت والجهد المطلوبَين لتحليل سلسلة وكيل المستخدم.

الفكرة هي أن تقدّم ترميزًا متوافقًا مع محركات البحث (link rel=alternate) في أعلى <head> يشير إلى إصدارات موقعك الإلكتروني التي تريد توفيرها.

<link rel="alternate" href="http://foo.com" id="desktop"
    media="only screen and (touch-enabled: 0)">

بعد ذلك، يمكنك إما رصد وكيل المستخدم من جهة الخادم والتعامل مع عملية إعادة التوجيه إلى الإصدار المناسب بنفسك، أو استخدام النص البرمجي device.js لإجراء عملية إعادة التوجيه من جهة العميل استنادًا إلى الميزات.

لمزيد من المعلومات، اطّلِع على صفحة مشروع device.js، بالإضافة إلى تطبيق وهمي يستخدم device.js لإعادة التوجيه من جهة العميل.

الاقتراح: MVC مع طرق عرض خاصة بشكل الجهاز

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

نأمل أن تكون قد استخدمت إطار عمل يشبه MVC، مثل Backbone أو Ember أو غيرهما. إذا كنت قد استخدمت إطار عمل، ستكون على دراية بمبدأ فصل الاهتمامات، وتحديدًا بأنّ واجهة المستخدم (طبقة العرض) يجب أن تكون منفصلة عن المنطق (طبقة النموذج). إذا كان هذا الموضوع جديدًا عليك، يمكنك البدء بالاطّلاع على بعض المراجع حول MVC وMVC في JavaScript.

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

الإحالات الناجحة على جميع الأجهزة
الإحالات الناجحة بعد رؤية الإعلان فقط على أجهزة متعدّدة:

قد يكون مشروعك على النحو التالي (بالطبع، يمكنك اختيار البنية التي تراها الأنسب لتطبيقك):

models/ (نماذج مشترَكة) item.js item-collection.js

controllers/ (shared controllers) item-controller.js

versions/ (محتوى خاص بالجهاز) tablet/ desktop/ phone/ (رمز خاص بالهاتف) style.css index.html views/ item.js item-list.js

يتيح لك هذا النوع من البنية التحكّم بشكل كامل في الأصول التي يتم تحميلها في كل إصدار، لأنّ لديك HTML وCSS وJavaScript مخصّصة لكل جهاز. هذه الميزة فعّالة جدًا، ويمكن أن تؤدي إلى توفير أسلوب بسيط وفعّال لتطوير تطبيقات الويب المتوافقة مع الأجهزة المختلفة، بدون الاعتماد على حيل مثل الصور المتجاوبة.

بعد تشغيل أداة الإنشاء المفضّلة لديك، سيتم دمج جميع ملفات JavaScript وCSS وتصغيرها في ملفات واحدة لتحميلها بشكل أسرع، وسيظهر رمز HTML الخاص بالإنتاج على النحو التالي (بالنسبة إلى الهاتف، باستخدام device.js):

<!doctype html>
<head>
  <title>Mobile Web Rocks! (Phone Edition)</title>

  <!-- Every version of your webapp should include a list of all
        versions. -->
  <link rel="alternate" href="http://foo.com" id="desktop"
      media="only screen and (touch-enabled: 0)">
  <link rel="alternate" href="http://m.foo.com" id="phone"
      media="only screen and (max-device-width: 650px)">
  <link rel="alternate" href="http://tablet.foo.com" id="tablet"
      media="only screen and (min-device-width: 650px)">

  <!-- Viewport is very important, since it affects results of media
        query matching. -->
  <meta name="viewport" content="width=device-width">

  <!-- Include device.js in each version for redirection. -->
  <script src="device.js"></script>

  <link rel="style" href="phone.min.css">
</head>
<body>
  <script src="phone.min.js"></script>
</body>

يُرجى العِلم أنّ طلب البحث عن الوسائط (touch-enabled: 0) غير متوافق مع المعايير (يتم تنفيذه في Firefox فقط باستخدام بادئة المورّد moz)، ولكن يتم التعامل معه بشكل صحيح (بفضل Modernizr.touch) من خلال device.js.

تجاوز الإصدار

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

ويتم عادةً توفير رابط يؤدي إلى نسخة الكمبيوتر المكتبي من النسخة المخصّصة للأجهزة الجوّالة. من السهل تنفيذ ذلك، ولكن تتيح أداة device.js هذه الوظيفة باستخدام المَعلمة device GET.

الخاتمة

باختصار، عند إنشاء واجهات مستخدم ذات صفحة واحدة تعمل على أجهزة متعددة ولا تتناسب مع التصميم السريع الاستجابة، اتّبِع الخطوات التالية:

  1. اختَر مجموعة من فئات الأجهزة التي تريد توفير الدعم لها، والمعايير التي سيتم بموجبها تصنيف الأجهزة إلى فئات.
  2. أنشئ تطبيق MVC مع فصل قوي بين المشاكل، مع تقسيم طرق العرض عن بقية قاعدة الرموز.
  3. استخدِم device.js لرصد فئة الجهاز من جهة العميل.
  4. عندما تصبح جاهزًا، يمكنك تجميع النصوص البرمجية وأوراق الأنماط في ملف واحد من كل نوع لكل فئة من فئات الأجهزة.
  5. إذا كان أداء إعادة التوجيه من جهة العميل يمثّل مشكلة، عليك التوقّف عن استخدام device.js والتحوّل إلى رصد وكيل المستخدم من جهة الخادم.