إنشاء نسخ من موقع HTML5 الإلكتروني

إيريك بيدلمان

المقدّمة

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

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

إنشاء html5rocks.com متوافق مع الجوال

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

تتناول هذه المقالة كيف أنشأنا إصدارًا للجوّال من html5rocks محسّن لأجهزة Android وiOS. ما عليك سوى تحميل html5rocks.com على جهاز يتوافق مع أحد أنظمة التشغيل هذه لترى الفرق. لا توجد عمليات إعادة توجيه إلى m.html5rocks.com أو إلى غيره من هذه العناصر. ويمكنك الحصول على html5rocks كما هي... مع الميزة الإضافية المتمثلة في أنه يبدو رائعًا ويعمل بشكل جيد على جهاز جوّال.

سطح المكتب html5rocks.com الجوال html5rocks.com
html5rocks.com على سطح المكتب (يسارًا) والهاتف الجوّال (يمينًا)

استعلامات وسائط CSS

كان HTML4 وCSS2 يدعمان أوراق الأنماط التي تعتمد على الوسائط لبعض الوقت. مثلاً:

<link rel="stylesheet" media="print" href="printer.css">

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

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

استهداف أحجام الشاشات

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

 <link rel='stylesheet'
  media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>

في حال بدء طلبات بحث عن الوسائط باستخدام الكلمة الرئيسية "only"، ستتجاهل المتصفِّحات غير المتوافقة مع CSS3 القاعدة.

يستهدف ما يلي أحجام الشاشات بين 641 بكسل و800 بكسل:

 <link rel='stylesheet'
  media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>

يمكن أن تظهر طلبات البحث عن الوسائط أيضًا ضمن علامات <style> مضمَّنة. في ما يلي استهداف أنواع الوسائط البالغ عددها all عندما يكون الاتجاه عموديًا:

 <style>
  @media only all and (orientation: portrait) { ... }
 </style>

media="handheld"

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

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

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

لا يتجاهل Opera Mini media="handheld". تكمن الحيلة في جعل Windows Mobile في التعرف على media="handheld" هي كتابة قيمة سمة الوسائط لورقة أنماط الشاشة بالأحرف الكبيرة:

 <!-- media="handheld" trick for Windows Mobile -->
 <link rel="stylesheet" href="screen.css" media="Screen">
 <link rel="stylesheet" href="mobile.css" media="handheld">

كيفية استخدام html5rocks للاستعلامات عن الوسائط

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

في <head> من كل صفحة، ستظهر لك أوراق الأنماط التالية:

 <link rel='stylesheet'
  media='all' href='/static/css/base.min.css' />
 <link rel='stylesheet'
  media='only screen and (max-width: 800px)' href='/static/css/mobile.min.css' />

لطالما حدّد الموقع الإلكتروني base.css المظهر والأسلوب الرئيسيَين لموقع html5rocks.com، ولكنّنا نطبّق الآن أنماطًا جديدة (mobile.css) لشاشات عرض تقل عن 800 بكسل. ويغطي الاستعلام عن الوسائط الهواتف الذكية (حوالي 320 بكسل) وجهاز iPad (حوالي 768 بكسل). التأثير: نحن بصدد إلغاء الأنماط تدريجيًا في base.css (عند الضرورة فقط) لتحسين مظهر الأجهزة على الأجهزة الجوّالة.

بعض تغييرات التصميم التي يفرضها mobile.css:

  • يقلل من المساحة البيضاء/المساحة المتروكة الزائدة على الموقع الإلكتروني. الشاشات الصغيرة تعني أن المساحة في غاية الأهمية!
  • يزيل :hover حالة. لن يمكن رؤيتها على الأجهزة التي تعمل باللمس.
  • يضبط التنسيق ليكون عمودًا واحدًا. سنتحدّث أكثر عن هذا الموضوع لاحقًا.
  • إزالة box-shadow حول الحاوية الرئيسية للموقع الإلكتروني، لأنّ الظلال المخصَّصة للمربّعات الكبيرة تعمل على تقليل أداء الصفحة
  • تم استخدام نموذج المربع المرن CSS box-ordinal-group لتغيير ترتيب كل قسم على الصفحة الرئيسية. ستلاحظ توفُّر "LEARN BY MAJOR HTML5 FEATURE Groups" (تعلم BY الرئيسيات مجموعات ميزات HTML5) يأتي قبل القسم "TUTORIALS" على الصفحة الرئيسية ولكن بعده على الإصدار المخصص للأجهزة الجوّالة. كان هذا الترتيب أكثر منطقيةً بالنسبة إلى الأجهزة الجوّالة، ولم يتطلّب إجراء تغييرات في الترميز. CSS flexbox FTW!
  • يؤدي إلى إزالة تغييرَين (opacity). يمثل تغيير قيم ألفا نتيجة أداء على الأجهزة الجوّالة.

العلامات الوصفية للأجهزة الجوّالة

تدعم Mobile WebKit بعض المزايا التي تمنح المستخدمين تجربة تصفح أفضل على أجهزة معينة.

إعدادات إطار العرض

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

 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">

يطلب من المتصفح ضبط إطار العرض على عرض الجهاز بمقياس أولي 1. يتيح هذا المثال أيضًا ميزة التكبير أو التصغير، وهي ميزة قد تكون مرغوبة في موقع إلكتروني وليس في تطبيق ويب. يمكننا منع التكبير أو التصغير باستخدام user-scalable=no أو ضبط الحجم على مستوى معيّن:

 <meta name=viewport
  content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">

يوسّع Android العلامة الوصفية لإطار العرض من خلال السماح للمطوّرين بتحديد درجة دقة الشاشة التي تم تطوير الموقع من أجلها:

 <meta name="viewport" content="target-densitydpi=device-dpi">

القيم المحتمَلة للسمة target-densitydpi هي device-dpi وhigh-dpi وmedium-dpi وlow-dpi.

إذا كنت تريد تعديل صفحة الويب لكثافة شاشة مختلفة، استخدِم طلب وسائط CSS -webkit-device-pixel-ratio و/أو السمة window.devicePixelRatio في JavaScript، ثم اضبط الخاصية الوصفية target-densitydpi على device-dpi. يمنع هذا Android من إجراء التحجيم في صفحة الويب، ويسمح لك بإجراء التعديلات اللازمة لكل كثافة، عبر CSS وJavaScript.

راجِع مستندات WebView الخاصة بنظام التشغيل Android للحصول على مزيد من المعلومات حول استهداف درجات دقة الأجهزة.

التصفُّح في وضع ملء الشاشة

هناك قيمتان تعريفيتان أخريان وهما iOS-sfic. سيعرض apple-mobile-web-app-capable وapple-mobile-web-app-status-bar-style محتوى الصفحة في وضع ملء الشاشة مثل التطبيق مع جعل شريط الحالة شفافًا:

 <meta name="apple-mobile-web-app-capable" content="yes">
 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

لمزيد من المعلومات حول جميع الخيارات الوصفية المتاحة، يمكنك الاطّلاع على المستندات المرجعية حول متصفّح Safari.

أيقونات الشاشة الرئيسية

تقبل أجهزة iOS وAndroid أيضًا rel="apple-touch-icon" (iOS) وrel="apple-touch-icon-precomposed" (Android) للروابط. تؤدي هذه الإعلانات إلى إنشاء رمز وامض يشبه التطبيق على الشاشة الرئيسية للمستخدم عندما يضع إشارة على موقعك الإلكتروني:

 <link rel="apple-touch-icon"
      href="/static/images/identity/HTML5_Badge_64.png" />
 <link rel="apple-touch-icon-precomposed"
      href="/static/images/identity/HTML5_Badge_64.png" />

كيفية استخدام html5rocks للعلامات الوصفية للجوّال

عند وضع كل شيء معًا، إليك مقتطف من القسم <head> من html5rocks:

 <head>
  ...
   <meta name="viewport"
        content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />

   <link rel="apple-touch-icon"
        href="/static/images/identity/HTML5_Badge_64.png" />
   <link rel="apple-touch-icon-precomposed"
        href="/static/images/identity/HTML5_Badge_64.png" />
  ...
 </head>

عرض رأسي

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

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

تحسينات الأجهزة الجوّالة

معظم التحسينات التي أجريناها هي أشياء كان من المفترض أن تتم في المقام الأول. وهي تشمل تقليل عدد طلبات الشبكة وضغط JS/CSS وgzipping (يتوفّر في App Engine مجانًا) وتقليل عمليات معالجة DOM. تُعدّ هذه التقنيات من أفضل الممارسات الشائعة، ولكن يتم تجاهلها أحيانًا عند دفع الموقع الإلكتروني عن طريق فتح الباب.

الإخفاء التلقائي لشريط العناوين

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

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

شريط العناوين
يشغل شريط العناوين المزعج مساحة الشاشة.
  // Hides mobile browser's address bar when page is done loading.
  window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);

لقد أوضحنا أيضًا أنّ أداة الاستماع هذه هي متغير النموذج is_mobile لأنها ليست مطلوبة على الكمبيوتر المكتبي.

تقليل طلبات الشبكة وتوفير معدّل نقل البيانات

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

في ما يلي بعض الأساليب التي اتبعناها لتقليل طلبات الشبكة وخفض معدل نقل البيانات على html5rocks:

  • إزالة إطارات iframe - إطارات iframe بطيئة كان مقدار وقت الاستجابة كبيرًا من خلال أدوات المشاركة من جهات خارجية (Buzz وGoogle Friend Connect وTwitter وFacebook) على صفحات البرامج التعليمية. تم تضمين واجهات برمجة التطبيقات هذه من خلال علامات <script> وإنشاء إطارات iframe تقلل من سرعة الصفحة. تمت إزالة التطبيقات المصغّرة للأجهزة الجوّالة.

  • display:none - في بعض الحالات، كنا نخفي الترميز إذا لم يتناسب مع الملف الشخصي على الأجهزة الجوّالة. خير مثال على ذلك هو المربعات الأربعة المستديرة في أعلى الصفحة الرئيسية:

أزرار المربع على الصفحة الرئيسية.
أزرار Box على الصفحة الرئيسية:

وهي غير متوفرة على الموقع الإلكتروني المتوافق مع الأجهزة الجوّالة. من المهم تذكُّر أنّ المتصفّح يواصل إرسال طلب لكل رمز، على الرغم من إخفاء الحاوية باستخدام display:none. لذلك، لم يكن إخفاء هذه الأزرار كافيًا ببساطة. لن يؤدي ذلك فقط إلى إهدار النطاق الترددي، ولكن المستخدم لن يرى ثمار هذا النطاق الترددي الضائع! كان الحل هو إنشاء قيمة منطقية "is_mobile" في نموذج Django لحذف أقسام HTML بشكل مشروط. عندما يشاهد المستخدم الموقع على جهاز ذكي، يتم ترك الأزرار.

  • ذاكرة التخزين المؤقت للتطبيق - لا يمنحنا ذلك الدعم في وضع عدم الاتصال فحسب، بل يؤدي أيضًا إلى إنشاء بدء تشغيل أسرع.

  • ضغط CSS/JS - نستخدم ضاغط YUI بدلاً من مجمع الإغلاق أساسًا لأنه يعالج كلاً من CSS وJS. كانت إحدى المشاكل التي واجهناها هي تخزين الاستعلامات عن الوسائط المضمّنة (طلبات البحث عن الوسائط التي تظهر داخل ورقة أنماط) في الإصدار 2.4.2 من أداة YUI compressor (راجِع هذه المشكلة). تم حلّ المشكلة من خلال استخدام الإصدار 2.4.4 من YUI بمتوسط الضاغط.

  • يتم استخدام صورة مدمجة من CSS قدر الإمكان.

  • تم استخدام pngcrush لضغط الصور.

  • تم استخدام dataURIs للصور الصغيرة. يضيف ترميز Base64 حجم +30%تقريبًا إلى الصورة ولكنه يحفظ طلب الشبكة.

  • تم تحميل بحث Google المخصص تلقائيًا باستخدام علامة نص برمجي واحدة بدلاً من تحميله ديناميكيًا باستخدام google.load(). ويقدم المستخدم الأخير طلبًا إضافيًا.

<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
  • فقد كان يتم تضمين طابعتنا الجميلة في الترميز وModernizr في كل صفحة، حتى لو لم يتم استخدامهما مطلقًا. برنامج Modernizr رائع لكنه يُجري مجموعة من الاختبارات عند كل تحميل تُجري بعض هذه الاختبارات تعديلات مكلفة على نموذج كائن المستند (DOM) وأبطئ تحميل الصفحة. والآن، نحن ندرج هذه المكتبات فقط في الصفحات التي تكون هناك حاجة إليها بالفعل. - طلبان :)

تعديلات إضافية على الأداء:

  • نقل كل محتوى JavaScript إلى أسفل الصفحة (حيثما أمكن).
  • تمت إزالة علامات <style> المضمّنة.
  • عمليات بحث DOM المخزنة مؤقتًا ومعالجة عناصر DOM المصغرة - في كل مرة تلمس فيها DOM، يجري المتصفح إعادة تدفق. تكون عمليات إعادة التدفق أكثر تكلفة على الجهاز المحمول.
  • تم تفريغ الرموز البرمجية من جهة العميل المُمهدة إلى الخادم. وعلى وجه التحديد، تظهر علامة الاختيار للتأكّد من ضبط نمط التنقّل للصفحة الحالية: js var lis = document.querySelectorAll('header nav li'); var i = lis.length; while (i--) { var a = lis[i].querySelector('a'); var section = a.getAttribute("data-section"); if (new RegExp(section).test(document.location.href)) { a.className = 'current'; } }
  • تم استبدال العناصر ذات العرض الثابت بالسائل width:100% أو width:auto.

ذاكرة التخزين المؤقت للتطبيق

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

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

ولمنع التخزين المؤقت المذكور على موقعنا الإلكتروني، نضبط أولاً App Engine على عدم تخزين ملفات البيان في ذاكرة التخزين المؤقت مطلقًا:

- url: /(.*\.(appcache|manifest))
  static_files: \1
  mime_type: text/cache-manifest
  upload: (.*\.(appcache|manifest))
  expiration: "0s"

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

window.applicationCache.addEventListener('updateready', function(e) {
  if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    window.applicationCache.swapCache();
    if (confirm('A new version of this site is available. Load it?')) {
      window.location.reload();
    }
  }
}, false);

لحفظ حركة بيانات الشبكة، أبقِ البيان بسيطًا. أي، لا تعلن عن كل صفحة على موقعك الإلكتروني. ما عليك سوى إدراج الصور المهمة وملفات CSS وJavaScript. آخر شيء تريد القيام به هو فرض تنزيل متصفح الجوال لعدد كبير من مواد العرض في كل تحديث لذاكرة التخزين المؤقت للتطبيقات. بدلاً من ذلك، تذكّر أنّ المتصفح سيخزّن ضمنيًا صفحة html مؤقتًا عندما يزورها المستخدم (يشمل ذلك السمة <html manifest="...">).