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

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

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

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

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

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

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

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

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

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

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

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

هناك طرفان ينتهيان لمجموعة المناهج:

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

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

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

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

حلّ محتمل

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

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

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

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

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

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

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

الطريقة الأولى: الاكتشاف من جهة الخادم

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

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

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

الطريقة الثانية: الاكتشاف من جهة العميل

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

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

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

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

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

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

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

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

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

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

اطّلع على مثال عملي على منهج اكتشاف الميزات.

يتمثل المنهج البديل هنا في استخدام خوارزمية UA للتعرّف على نوع الجهاز. تقوم في الأساس بإنشاء مجموعة من الإرشادات ومطابقتها مع 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، ولكن قد يكون هذا بطيئًا و/أو غير دقيق، حسب نوع تطبيقك.

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

في ما يلي المفاضلات بين الأساليب:

عميل Pro:

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

خادم Pro:

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

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

لمحة عن device.js

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

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

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

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

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

الاقتراح: جذب العميل الأكثر قيمة مع مشاهدات محدّدة لعوامل الشكل

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

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

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

MVC عبر الأجهزة.
جذب العملاء الأكثر قيمة (MVC) على جميع الأجهزة

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

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

consoles/ (وحدات التحكّم المشتركة) item-controller.js

الإصدارات/ (عناصر خاصة بالجهاز) Tablet/ سطح المكتب/ الهاتف/ (رمز خاص بالهاتف) 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 يدعم هذه الوظيفة مع معلمة GET device.

الخاتمة

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

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