مقدمة
يُعدّ تطوير الويب على الأجهزة الجوّالة موضوعًا رائجًا هذه الأيام. هذا العام، ولأول مرة على الإطلاق، تجاوزت مبيعات الهواتف الذكية مبيعات أجهزة الكمبيوتر الشخصية. يستخدم المزيد والمزيد من المستخدمين جهازًا جوالاً لتصفح الويب، مما يعني أنه أصبح من الضروري للمطورين تحسين مواقعهم الإلكترونية لمتصفحات الأجهزة الجوّالة.
لا يزال مجال "الأجهزة الجوّالة" غير مألوف لعدد كبير من المطوّرين. يملك العديد من الأشخاص مواقع إلكترونية قديمة تتجاهل مستخدمي الأجهزة الجوّالة تمامًا. بدلاً من ذلك، تم تصميم الموقع في المقام الأول لتصفح متصفّح متوافق مع أجهزة الكمبيوتر المكتبي ويتدهور بشكل سيئ في متصفّح الأجهزة الجوّالة. وهذا الموقع الإلكتروني (html5rocks.com) ليس استثناءً. عند الإطلاق، لم نبذل جهدًا كبيرًا في إنشاء نسخة من الموقع الإلكتروني مخصّصة للأجهزة الجوّالة.
إنشاء موقع html5rocks.com متوافق مع الأجهزة الجوّالة
كتمرين، اعتقدت أنه سيكون من المثير للاهتمام استخدام html5rocks (موقع HTML5 الحالي) وزيادته بإصدار متوافق مع الأجهزة الجوّالة. كنت مهتمًا بشكل أساسي بالحد الأدنى من العمل المطلوب لاستهداف الهواتف الذكية. لم يكن الهدف من التمرين هو إنشاء موقع إلكتروني جديد بالكامل للأجهزة الجوّالة والاحتفاظ بقاعدتَي رموز برمجية. كان ذلك سيستغرق وقتًا طويلاً وكان سيضيع الكثير من الوقت. لقد حدّدنا مسبقًا بنية الموقع الإلكتروني (الترميز). كان لدينا مظهر وأسلوب (CSS). وكانت الوظيفة الأساسية (JS) متوفّرة. المقصود هو أنّ العديد من المواقع الإلكترونية تواجه المشكلة نفسها.
تتناول هذه المقالة كيفية إنشاء نسخة الموقع الإلكتروني المخصّصة للأجهزة الجوّالة من html5rocks ومحسّنة لأجهزة Android وأجهزة iOS. ما عليك سوى تحميل html5rocks.com على جهاز متوافق مع أحد أنظمة التشغيل هذه لمعرفة الفرق. لا توجد عمليات إعادة توجيه إلى m.html5rocks.com أو أي حيل أخرى من هذا النوع. ستحصل على html5rocks كما هو… مع ميزة إضافية تتمثل في شيء يبدو رائعًا ويعمل بشكل جيد على جهاز محمول.
طلبات البحث عن الوسائط في 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 بكسل).
The effect: we're incrementally overriding styles in base.css (only as necessary)
to make things look better in mobile.
بعض التغييرات في الأنماط التي يفرضها mobile.css:
- يقلّل من المساحة البيضاء/المساحة المتروكة الإضافية في الموقع الإلكتروني. الشاشات الصغيرة تعني أنّ المساحة محدودة.
- تتم إزالة ولايتَين (
:hover). ولن تظهر أبدًا على الأجهزة التي تعمل باللمس. - يتم تعديل التنسيق ليكون عمودًا واحدًا. سنتحدّث عن ذلك بالتفصيل لاحقًا.
- تزيل هذه الإضافة السمة
box-shadowحول عنصر div للحاوية الرئيسية في الموقع الإلكتروني، لأنّ ظلال المربّعات الكبيرة تقلّل من أداء الصفحة. - تم استخدام نموذج CSS flex box
box-ordinal-groupلتغيير ترتيب كل قسم في الصفحة الرئيسية. ستلاحظ أنّ قسم "LEARN BY MAJOR HTML5 FEATURE GROUPS" يظهر قبل قسم "TUTORIALS" على الصفحة الرئيسية، ولكنّه يظهر بعده في نسخة الموقع الإلكتروني المخصّصة للأجهزة الجوّالة. كان هذا الترتيب أكثر منطقية للأجهزة الجوّالة ولم يتطلّب إجراء تغييرات في الترميز. نموذج CSS flexbox هو الأفضل! - تتم إزالة تغييرات
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.
إذا أردت تعديل صفحة الويب لتناسب كثافات الشاشة المختلفة، استخدِم الاستعلام عن الوسائط -webkit-device-pixel-ratio في CSS و/أو السمة window.devicePixelRatio في JavaScript، ثم اضبط السمة الوصفية target-densitydpi على device-dpi. يؤدي ذلك إلى منع Android من إجراء عملية تغيير الحجم في صفحة الويب، ويتيح لك إجراء التعديلات اللازمة لكل كثافة، من خلال CSS وJavaScript.
يمكنك الاطّلاع على مستندات WebView في Android لمزيد من المعلومات حول استهداف درجات دقة الأجهزة.
التصفّح بملء الشاشة
هناك قيمتان وصفيّتان أخريان خاصتان بنظام التشغيل iOS. 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 لإنشاء هذا التنسيق. مرة أخرى، بدون تغيير الترميز.
تحسينات للأجهزة الجوّالة
معظم التحسينات التي أجريناها هي أشياء كان ينبغي القيام بها في المقام الأول. مثل تقليل عدد طلبات الشبكة، وضغط 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- في بعض الحالات، كنّا نخفي الترميز إذا لم يكن مناسبًا للملف الشخصي على الأجهزة الجوّالة. ومن الأمثلة الجيدة على ذلك المربّعات الأربعة المستديرة في أعلى الصفحة الرئيسية:
وهي غير متوفّرة على الموقع الإلكتروني للأجهزة الجوّالة. من المهم تذكُّر أنّ المتصفّح لا يزال يرسل طلبًا لكل رمز، على الرغم من أنّ الحاوية مخفية باستخدام display:none. وبالتالي، لم يكن كافيًا
إخفاء هذه الأزرار فقط. لن يؤدي ذلك إلى إهدار معدل نقل البيانات فحسب، بل لن يرى المستخدم
حتى ثمار معدل نقل البيانات المهدر! كان الحلّ هو إنشاء قيمة منطقية "is_mobile" في نموذج Django لحذف أقسام من HTML بشكل مشروط.
عندما يشاهد المستخدم الموقع على جهاز ذكي، يتم استبعاد الأزرار.
ذاكرة التخزين المؤقت للتطبيق: لا يتيح لنا ذلك العمل بلا إنترنت فحسب، بل يتيح أيضًا بدء التشغيل بشكل أسرع.
ضغط CSS/JS: نستخدم أداة ضغط YUI بدلاً من برنامج تجميع Closure لأنّها تتعامل مع كل من CSS وJS. من المشاكل التي واجهتنا أنّ الاستعلامات عن الوسائط المضمّنة (التي تظهر داخل ورقة الأنماط) لم تكن تعمل في YUI compressor 2.4.2 (يمكنك الاطّلاع على هذه المشكلة). وقد تم حلّ المشكلة باستخدام YUI Compressor 2.4.4+.
استخدام صور CSS المجمّعة حيثما أمكن ذلك
تم استخدام pngcrush لضغط الصور.
تم استخدام dataURIs للصور الصغيرة. يضيف ترميز Base64 ما يزيد عن%30 من الحجم إلى الصورة، ولكنه يحفظ طلب الشبكة.
تم تحميل "بحث Google المخصّص" تلقائيًا باستخدام علامة برمجية واحدة بدلاً من تحميله ديناميكيًا باستخدام
google.load(). ويقدّم الأخير طلبًا إضافيًا.
<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
- كان يتم تضمين أداة عرض الرموز بتنسيق محسّن وModernizr في كل صفحة، حتى إذا لم يتم استخدامهما مطلقًا. Modernizr هي أداة رائعة، ولكنها تُجري مجموعة من الاختبارات عند كل تحميل. تُجري بعض هذه الاختبارات تعديلات مكلفة على نموذج العناصر في المستند (DOM) وتؤدي إلى إبطاء تحميل الصفحة. الآن، نضمّن هذه المكتبات فقط في الصفحات التي تحتاج إليها فعليًا. -2 requests :)
تعديلات إضافية على الأداء:
- نقلتُ كل ملفات JS إلى أسفل الصفحة (حيثما أمكن).
- تمت إزالة علامات
<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="...">).