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

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

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

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

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

تحتاج التطبيقات على الويب إلى أكثر من طلبات البحث عن الوسائط.

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

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

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

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

مجموعة متنوعة من الأجهزة
مجموعة متنوعة من الأجهزة (source).

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

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

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

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

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

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

حلّ محتمل

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

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

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

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

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

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

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

الطريقة 1: رصد المحتوى من جهة الخادم

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

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

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

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

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

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

ملاحظة سريعة حول وحدات البكسل في CSS: لا تُعدّ وحدات البكسل في CSS على الويب على الأجهزة الجوّالة مماثلة لوحدات البكسل على الشاشة. وقد ظهرت ميزة التضاعف في كثافة وحدات البكسل على أجهزة iOS التي تتضمّن شاشة بتقنية "العرض الفائق الدقة" (مثل iPhone 3GS مقارنةً بـ iPhone 4 وiPad 2 مقارنةً بـ iPad 3). لا تزال وحدات Universal Analytics على أجهزة Safari للأجهزة الجوّالة ذات الشاشة العالية الدقة تُبلغ عن عرض الجهاز نفسه لتجنُّب تعطُّل الويب. مثل الأجهزة الأخرى (مثل Android) شاشات بدقة أعلى، إلا أنّها تستخدم الحيلة نفسها المتعلّقة بعرض الجهاز.

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

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

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

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

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

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

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

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

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

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

اطّلِع على عيّنة من نهج رصد Universal Analytics.

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

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

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

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

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

تحديد العميل أو الخادم

في ما يلي المفاضلة بين النهجَين:

العميل المحترف:

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

الخادم الاحترافي:

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

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

نبذة عن device.js

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

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

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

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

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

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

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

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

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

نموذج التفاعل بين العميل والعرض (MVC) على جميع الأجهزة
الحملات على جميع الأجهزة (MVC)

قد يتضمّن مشروعك البنية التالية (بطبيعة الحال، أنت حر في اختيار البنية التي تناسبك أكثر استنادًا إلى طلبك):

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

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) media غير عادي (يتم تنفيذه فقط في Firefox باستخدام بادئة moz الخاصة بالمطوّر)، ولكن يتم التعامل معه بشكلٍ صحيح (بفضل Modernizr.touch) من خلال device.js.

إلغاء الإصدار

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

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

الخاتمة

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

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