-
المساهمات
164 -
تاريخ الانضمام
-
تاريخ آخر زيارة
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو ابراهيم الخضور
-
يقدِّم لك هذا المقال خلفيةً مفيدةً حول عالم الويب وظهوره والتقنيات المعيارية له وكيف تعمل معًا، كما يطلعك على تمّيز مهنة مطوري الويب وعن الممارسات العملية الأفضل التي عليك تعلّمها. موجز عن تاريخ ويب سنختصر الأمر قدر المستطاع لوجود الكثير من المعلومات المفصّلة عن تاريخ ويب خارج إطار هذا المقال والتي سنشير إليها لاحقًا، ويمكنك أيضًا البحث باستخدام أحد محركات البحث المفضلة لديك إذا كنت مهتمًا بتفاصيل أكثر. طوّر الجيش الأميريكي في ستينيات القرن الماضي شبكة اتصال دُعيت آربانت ARPANET، إذ يمكن عدّ هذه الشبكة هي البداية المبكرة لويب، وقد استخدمت تقنية تحويل أو تبديل حزم البيانات وشهدت أول تنفيذ لمجموعة بروتوكولات TCP/IP، كما تُشكِّل التقنيتين السابقتين البنية التحتية التي قامت عليها شبكة الإنترنت. كتب تيم برنرز-لي Tim Berners-Lee -ويشار إليه عادةً بالاسم TimBL- عام 1980 برنامجًا نصيًا دُعي "ENQUIRE" والذي مهَّد لمفهوم الربط بين العقد المختلفة، أيبدو مألوفًا؟ وبتسريع الوقت حتى عام 1989، إذ كتب تيم عملَين أحدهما بعنوان "مقترح لإدارة المعلومات Information Management: A Proposal" والآخر بعنوان النص التشعبي HyperText خلال عمله مستشارًا في المنظمة الأوروبية للطاقة النووية CERN، وقد قدّم هذان العملان خلفيةً معرفيةً عن الكيفية التي يفُتَرض أن تعمل بها ويب، كما وتلقى العملان كمًا لا بأس به من الاهتمام، وكان هذا كافيًا ليسمح له مديروه بمتابعة العمل نحو إنشاء منظومة نصوص تشعبية عالمية؛ أما بحلول عام 1990، فقد كان تيم قد أنشأ كل الأشياء الضرورية اللازمة لتشغيل النسخة الأولى لويب.بروتوكول HTTP ولغة HTML، بالإضافة إلى متصفح ويب الأول والذي دُعيَ حينها WorldWideWeb وخادم HTTP وبعض صفحات ويب لاستعراضها. توسّع عالم الويب بشدة في السنوات التي تلت مع ظهور عدد من المتصفحات الجديدة وإعداد آلاف خوادم ويب وكتابة ملايين الصفحات، ولا بد من الإشارة في هذه العجالة إلى تأسيس تيم لمجمّع World Wide Web Consortium واختصارًا W3C، وهي منظمة تجمع ممثلين عن شركات تقنية عالمية مختلفة للعمل معًا لوضع مواصفات ومعايير للويب، وبعد ذلك ظهرت تقنيات مثل CSS ومن ثم جافاسكربت وأخذت تبدو الويب بعدها شبيهةً بما هي عليه اليوم. معايير ويب تُعَدّ معايير ويب Web standards التقنيات التي نستخدِمها لبناء مواقع الويب، إذ تظهر هذه المعايير على هيئة مستندات تقنية طويلة تُدعى التوصيفات specifications والتي تفصّل تمامًا الطريقة التي ينبغي لتقنية ما العمل وفقها، كما لا تقدِّم هذه المستندات فائدةً كبيرةً في تعلّم استخدام التقنية التي تصفها ولذلك وُجِدت مواقع مثل موسوعة حسوب وتوثيق MDN التي تعرض التوثيقات بطريقة مختصرة ومبسطة، وإنما هي موجَّهة إلى مهندسِي البرمجيات لتطبيق هذه التقنيات، إذ يصف المستند HTML Living Standard على سبيل المثال كيفية تطبيق شيفرة HTML تمامًا، أي جميع عناصر اللغة، والواجهات البرمجية المرتبطة بها، وغير ذلك من التقنيات المحيطة بها. تُنشَأ معايير ويب من قِبَل هيئات قياسية مثل المنظمات والمعاهد التي تدعو تِقنيين من شركات مختلفة للاتفاق على أفضل الطرائق التي ينبغي أن تعمل وفقها التقنيات لتلبي احتياجاتهم، إذ تُعَدّ W3C من أهم هذه الهيئات، ونجد أيضًا WHATWG التي تصون وتطوِّر المعايير المستخدم للغة HTML، و ECMA التي تنشر معايير ECMAScript التي تُبنى عليها جافاسكربت، و Khronos التي تنشر تقنيات الرسوميات ثلاثية الأبعاد مثل WebGL وغيرها من الهيئات. المعايير مفتوحة المصدر لا بد أن تبقى الويب وتقنياتها مجانيةً للمساهمين في بنائها ومستخدِميها وغير خاضعة لبراءات الاختراع أو رخص الاستخدام، وهذا الموضوع هو الميزة الأساسية لمعايير ويب والتي وافق عليها تيم-لي ومجمّع W3C منذ البداية، لذلك يمكن لأيّ كان كتابة الشيفرات مجانًا لبناء موقع ويب، كما يمكن لأيّ كان المساهمة في عملية تطوير وإنشاء معايير ويب. لا يمكن لأي شركة التحكم بتقنيات الويب لأنها بُنيَت لتكون مفتوحة المصدر بالتعاون بين شركات مختلفة، وهذا أمر جيد حقًا، فلن ترغب مطلقًا أن تضع أيّ شركة قيودًا ماليةً على تقنيات ويب فجأة، أو أن تصدر نسخةً مدفوعةً من HTML عليك شرائها لتستمر في استخدامها، أو أن تقرر الشركة -في أسوأ سيناريو- أنّ الموضوع لم يَعُد يهمها ثم توقف العمل به، وبالتالي يسمح هذا الأمر ببقاء الويب وتقنياتها متاحةً مجانًا للجميع. لا تفكك الويب قد تسمع بمصطلح آخر يتعلق بمعايير ويب هو "لا تفكك الويب"، ويعني ذلك أنّ أيّ تقنية جديدة في عالم الويب لا بد وأن تكون متوافقةً مع ما بُني سابقًا -أي يجب استمرار مواقع الويب القديمة بالعمل-، ومع ما سيُبنى لاحقًا -أي أن التقنيات التي ستظهر لاحقًا لا بد أن تبقى متوافقة مع التقنيات الحالية-، ومع تقدمك في مسيرتك في التعلم ستعرف كيف يتحقق ذلك من خلال التصميم والتنفيذ الذكي لهذه المفاهيم. من الجيد أن تكون مطور ويب تُعَدّ صناعة الويب سوقًا ملفتًا ومهمًا إذا كنت تبحث عن عمل، وتشير الأرقام الحالية إلى وجود أكثر من 19 مليون مطور ويب في العالم، وسيتضاعف هذا العدد في العقد القادم، وفي الوقت ذاته، هناك نقص في الخبرات ضمن هذه الصناعة، لذلك فالوقت الآن مناسب جدًا من أجل تعلم تطوير مواقع ويب. لا تتعلق صناعة الويب فقط بأمور الترفيه والألعاب، وإنما يزداد تعقيد بناء مواقع الويب عما كان عليه، إذ عليك قضاء المزيد من الوقت في دراسة التقنيات المختلفة التي ستستخدِمها، وجميع الأساليب والممارسات العملية التي يجب تعلمها، والنماذج التقليدية التي سيطلب منك إنجازها، فقد تحتاج أشهرًا عدة لتبدأ باستيعابها، وبعد ذلك عليك الاستمرار في تعلم المزيد لكي تبقى معلوماتك مواكبةً لآخر التطورات بما في ذلك الأدوات والميزات الجديدة التي تظهر على منصات عمل ويب، كما عليك التمرن أكثر لصقل مهاراتك في هذه المهنة. هل يبدو الأمر صعبًا؟ نسعى في هذا السياق إلى منحك كل الإمكانات لتنطلق ومن ثم ستسهل بقية الأمور عليك، فحالما تعتنق مفهومَي التغيُّر والشك في عالم ويب، فستستمتع بما تفعله، وعلى أساس أنك فرد في مجتمع ويب، فستجد شبكةً كاملةً من المعارف والمواد القيّمة التي ستساعدك وسترى الإمكانات الإبداعية التي يوفّرها هذا العمل، كما ستغدو مبدعًا في العالم الرقمي، فاستمتع إذًا بهذه التجربة وبالمكاسب المحتملة التي ستحققها في تجربتك في تطوير الويب. نظرة على بعض تقنيات ويب العصرية لا بد أن تتعلم عددًا من التقنيات إذا قررت أن تصبح مطورًا للواجهات الأمامية، لذلك سنصف في هذه الفقرة هذه التقنيات باختصار. المتصفحات ربما تستخدِم الآن متصفحًا لقراءة هذا المقال، فالمتصفحات هي برمجيات يستخدِمها الناس ليستعرضوا محتويات الويب ويتفاعلوا معها مثل فايرفوكس وكروم وأوبرا وسفاري وإيدج. بروتوكول HTTP يُعَدّ بروتوكول نقل النص التشعبي Hypertext Transfer Protocol واختصارًا HTTP بروتوكولًا لنقل الرسائل التي تسمح للمتصفح بالتواصل مع خوادم ويب (المكان الذي تُثبت عليه مواقع الويب)، إذ تجري المحادثة النمطية بين المتصفح والخادم بصورة تشبه التالي: "Hello web server. Can you give me the files I need to render bbc.co.uk"? "Sure thing web browser — here you go" [Downloads files and renders web page] لا يمكن للبشر بالطبع قراءة الصيغة الفعلية لرسائل التواصل والتي تُدعى طلبات واستجابات، لكن قد يعطيك مثالنا السابق تصوّرًا عن العملية. HTML و CSS وجافاسكربت وهي التقنيات الرئيسية الثلاث التي سنستخدِمها لبناء مواقع ويب: HTML لغة ترميز النصوص التشعبية Hypertext markup language: وهي لغة ترميزية تتكون من عناصر مختلفة يمكن أن تُغلِّف محتوى ويب ضمنها وتوضِّح معناها وهيكليتها، إذ تبدو شيفرة HTML البسيطة قريبة من التالي: <h1>This is a top-level heading</h1> <p>This is a paragraph of text.</p> <img src="cat.jpg" alt="A picture of my cat"> يمكنك تشبيه اللغة إذا وازنتها مع بناء سكني بأساسات وجدران المنزل التي تعطيه شكله وتجعله متماسكًا. CSS التنسيقات المورثة Cascading Style Sheets: وهي لغة مبنية على قواعد مخصصة لتطبيق تنسيقات معينة على عناصر HTML مثل ضبط ألوان النصوص والخلفيات وإضافة الأطر وتحريك الأشياء أو تخطيط الصفحة بطريقة معينة، وإليك مثالًا بسيطًا يحوِّل نصوص الفقرات <p> في HTML إلى اللون الأحمر: p { color: red; } ووفقًا لتشبيه المنزل السكني، فستكون CSS بمثابة الطلاء وورق الجدران والسجاد واللوحات التي تضعها داخل المنزل. جافاسكربت JavaScript: هي لغة البرمجة التي تستخدِمها لإضافة التفاعل في مواقع الويب، ابتداءً بالتغيير الديناميكي للتنسيق إلى إحضار البيانات من الخادم مرورًا بتنفيذ الرسوميات ثلاثية الأبعاد، إذ ستخزِّن شيفرة جافاسكربت التالية على سبيل المثال مرجعًا إلى عنصر الفقرة <p> ومن ثم تغيّر النص الموجود ضمنه: let pElem = document.querySelector('p'); pElem.textContent = 'We changed the text!'; وبالعودة لتشبيه المنزل السكني، فستكون جافاسكربت بمثابة الطباخ أو التلفاز أو مجفف الشعر، أي الأشياء التي تزيد من إمكانات منزلك. الأدوات حالما تتعلم التقنيات الأساسية التي تُستخدم في بناء صفحات الويب، فستبدأ بالتعرف على أدوات عديدة تُسهِّل عملية بناء الصفحات وتجعلها أكثر فاعليةً، وإليك بعض الأمثلة: أدوات مطوري ويب الموجودة في المتصفحات العصرية والتي تُستخدم في تنقيح شيفرتك. أدوات الاختبار التي تُستخدم في تنفيذ اختبارات تظهر سلوك شيفرتك إذا حققت المطلوب أم لا. المكتبات وأطر العمل frameworks المبنية على أساس جافاسكربت والتي تسمح بتطوير أنواعًا مختلفةً من مواقع الويب بطرق أسرع وأكثر فاعليةً. المنقِّحات Linters التي تحدِّد مجموعةً من القواعد وتدقق شيفرتك بحثًا عن أيّ خرق لهذه القواعد. المُصغِّرات Minifiers التي تزيل المساحات الفارغة من الشيفرة لتبدو أقل حجمًا، وبالتالي ستزداد سرعة تنزيلها من خوادم الويب. اللغات التي تنفذ ضمن الخوادم وأطر العمل المتعلقة بها تُعَدّ HTML و CSS وجافاسكربت لغات تعمل في الواجهة الأمامية (من جهة العميل)، أي أنها تُنفَّذ باستخدام المتصفحات لتظهر صفحة الويب كما يراها المستخدِم. هناك أيضًا مجموعة أخرى من لغات البرمجة تُدعى لغات الواجهة الخلفية (من جهة الخادم) أي أنها تُنفّذ على الخادم قبل أن تًرسل نتيجة التنفيذ إلى المتصفح لعرضها، إذ يقتصر الاستخدام النمطي لهذه اللغات على الحصول على بعض البيانات من قواعد البيانات ومن ثم توليد شيفرة HTML لاحتواء هذه البيانات وإرسالها إلى المتصفح ليعرضها للمستخدِم، ونذكر من هذه اللغات ASP.NET و Python و PHP و NodeJS. أفضل الممارسات عند تطوير مواقع الويب تحدثنا بإيجاز عن التقنيات التي ستستخدِمها في بناء مواقع الويب، وسنتحدث الآن عن أفضل الممارسات العملية التي عليك تبنيها لتتأكد من استخدام تلك التقنيات بأفضل طريقة ممكنة. سيأتي المصدر الأساسي لعدم الثقة عندما نتحدث عن تصميم مواقع ويب من عدم معرفتك بمجموعة التقنيات التي يعتمد عليها المستخدِمين في تصفح موقعك: قد يستخدِم أحدهم جهاز آيفون بشاشة صغيرة وضيقة. قد يستخدِم آخر حاسوبًا محمولًا بنظام ويندوز له شاشة عرض واسعة. أما الثالث فقد يكون ضريرًا ويستخدم قارئًا آليًا لمحتوى الشاشة. وقد يستخدم الرابع حاسوبًا مكتبيًا قديمًا لا يستطيع تشغيل أية متصفحات حديثة. عليك تصميم موقعك وفق الآلية الدفاعية بما أنك لا تعرف ببساطة كيف سيتصفحه المستخدِم، ف، لذا اجعل موقعك مرنًا قدر الإمكان لكي يتمكن جميع المستخدِمين من الوصول إلى محتواه بصرف النظر عن اختلاف تجربتهم له، أي عليك باختصار إفادة الجميع من الويب قدر المستطاع، كما ستصادف في مرحلة ما من رحلتك التعليمية المفاهيم التالية: التوافق مع متصفحات مختلفة Cross-browser compatibility: وهو أسلوب يحاول التأكد من عمل صفحة الويب بالصورة المطلوبة ضمن أكبر عدد ممكن من المتصفحات، ويتضمن ذلك استخدام تقنيات تدعمها معظم المتصفحات، وتقديم تجربة تصفح أفضل في المتصفحات القادرة على التعامل مع هذه التقنيات (تحسين مستمر)، وكتابة شيفرة يمكن اختزالها بسهولة إلى صيغة أبسط تستطيع المتصفحات القديمة عرضها لإعطاء تجربة تصفح مفيدة (تراجع رشيق graceful degradation)، كما يتضمن الأمر الكثير من الاختبارات لمتابعة أي مشاكل على متصفح محدد، ومن ثم العمل أكثر على إصلاح تلك المشاكل. تصميم متجاوب للصفحات Responsive web design: وهو أسلوب لخلق مرونة من الناحية الوظيفية والتخطيطية للصفحات بحيث تتلاءم تلقائيًا مع المتصفحات المختلفة، ومثالنا على ذلك صفحة ويب تُعرَض بتخطيط معيّن على شاشة واسعة لمتصفح حاسوب ومن ثم تأخذ تخطيطًا متجاوبًا مع حجم الشاشة مثل تخطيط العمود الواحد على متصفح هاتف محمول، إذ يمكنك تجريب أيّ موقع على الأحجام الصغيرة بتصغير حجم نافذة المتصفح وملاحظة سلوكه المتجاوب مع الأحجام الصغيرة الأداء Performance: ويستهدف تحميل صفحة ويب بالسرعة الممكنة مع المحافظة على وضوحها وسهولة استخدامها لكي لا يشعر المستخدِم بالإحباط ويغادرها. سهولة الوصول Accessibility: ويعني إمكانية استخدام الموقع من قِبَل أكبر عدد ممكن من الأشخاص المختلفين من جميع النواحي وترتبط بمفاهيم مثل التنوع، والشمولية، والتصميم الشمولي، كما يتضمن ذلك أشخاصًا ذوي إعاقة بصرية أو سمعية أو إدراكية أو حركية، ويتعدى الأمر مفهوم الإعاقة إلى السن والثقافة والتجهيزات المستخدَمة والمحدودية التقنية مثل الاتصال البطيء بالإنترنت. التدويل Internationalization: ويعني ذلك إمكانية استخدام موقع الويب من قِبَل أشخاص ينتمون إلى ثقافات مختلفة أو يتكلمون لغات مختلفة عن لغتك، وهنالك اعتبارات تقنية للموضوع مثل تبديل تخطيط الصفحات ليتلاءم مع اللغات التي تُكتَب من اليمين إلى اليسار أو مع اللغات التي تكتب عموديًا، واعتبارات إنسانية مثل استخدام لغة بسيطة وواضحة بعيدة عن اللهجات، ليزداد احتمال فهم الأشخاص الذين يتكلمون لغتك على أساس لغة ثانية أو ثالثة لما تعرضه. الخصوصية والأمان Privacy & Security: يرتبط المفهومان ببعضهما لكنهما مختلفان، إذ تعني الخصوصية السماح للأشخاص بتنفيذ ما يريدونه دون أن تتجسس على نشاطاتهم أو تجمع أية بيانات أكثر مما تحتاجه فعلًا، بينما يعني الأمان بناء موقعك بطريقة لا تُمكّن المستخدِمين المشبوهين من سرقة المعلومات التي يضمها الموقع عنك أو عن عملائك. الانطلاق في عالم ويب سنعرض في هذا المقال بعض المهارات العملية اللازمة لتنطلق في عالم تطوير ويب مثل اختيار البرمجيات التي تعمل عليها والأدوات اللازمة لبناء صفحات ويب بسيطة ونشرها وكتابة شيفرتها، كما سنفرد لاحقًا لكل العناوين التي نمر عليها مقالات خاصةً لشرح مستفيض أكثر. عليك الكثير لتتعلمه وتفعله حتى تصل إلى مرحلة تطوير موقع ويب احترافي، فإذا كنت حديث العهد في هذا المجال، فسنشجِّعك على البدء بموقع بسيط، ولن تكون جاهزًا مباشرةً لتبني موقع فيسبوك جديد، لكنك ستكون قادرًا على بناء مواقع بسيطة ونشرها، وبالاطلاع على المقالات التي سنشير إليها باختصار والعمل بمضمونها، ستنتقل من الصفر إلى نشر أول موقع بسيط لك على الإنترنت، فلنبدأ جولتنا. تثبيت البرمجيات الأساسية هناك الكثير من الأدوات والبرمجيات التي تُستخدَم في بناء وتطوير مواقع ويب، وقد تربكك بالفعل كثرة محررات الشيفرة وإطارات العمل وأدوات الاختيار، إذ سنرشدك في مقال تثبيت البرمجيات الأساسية خطوةً بخطوة إلى تثبيت البرمجيات التي تحتاجها لتبدأ عملية بناء مواقع ويب بسيطة. التفكير بالمظهر العام لموقع الويب الذي تبنيه عليك التخطيط لمظهر ومحتوى موقعك قبل الشروع في كتابة الشيفرة، فما هي المعلومات التي سيعرضها؟ وما هي خطوط الكتابة والألوان التي ستستخدِمها؟ التعامل مع الملفات يتكون موقع ويب من ملفات عدة: نصية وشيفرات وأوراق تنسيق ووسائط متعددة وغيرها. لا بد إذًا من تنظيم هذه الملفات وفق هيكلية منطقية عندما تبدأ بناء موقعك وأن تتأكد من ترابط هذه الملفات مع بعضها. أساسيات HTML تُستخدَم شيفرة HTML في هيكلة محتوى ويب وتعطيه المعنى والغاية، أي هل المحتوى الذي تقدِّمه على سبيل المثال سيكون مقطعًا نصيًا أم قائمة نقطية؟ هل ستزوِّد صفحتك بالصور؟ هل ستعرض جداول تضم بيانات؟ أساسيات CSS تُعَدّ التنسيقات المورثة Cascading Style Sheets واختصارًا CSS شيفرةً خاصةً بتنسيق صفحات ويب، فهل سيكون نص ما مثلًا أسود أم أحمر؟ في أيّ مكان من الصفحة ستعرض محتوًى معينًا؟ ما الصورة التي ستضعها في خلفية الصفحة؟ أو ما الألوان التي ستختارها لموقعك؟ أساسيات جافا سكربت جافا سكريبت هي لغة البرمجة التي تستخدمها لإضافة ميزات تفاعلية إلى موقعك مثل الألعاب أو الأشياء التي تحدث عند النقر على زر أو عندما تُدخل نصًا في نموذج أو عندما تُحدث تأثيرات حركية في تنسيق العناصر أو عند تصميم الرسوميات المتحركة وغيرها الكثير. نشر موقعك على شبكة الإنترنت عندما تُنهي كتابة شيفرة موقعك وتنظيم جميع الملفات التي يضمها، سيحين الوقت لنشره على شبكة الإنترنت ليطَّلع عليه الناس. كيف يعمل الويب قد لا تكون لديك فكرة عن الأشياء المعقدة التي تجري خلف الستار عندما تتصفح مواقعك المفضلة، لكننا سنختصر ما يحدث في جزئية لاحقة من هذه السلسلة عندما تستعرض صفحة ويب في متصفح حاسوبك. ختامًا، قد يهمك مقال آلية عمل شبكة الإنترنت؟، وقد ترغب بالاطلاع أكثر على تاريخ الشبكة العنكبوتية العالمية، وننصحك أيضًا بالرجوع إلى مقالة المدخل الشامل لتعلم تطوير الويب ترجمة -وبتصرف- للمقال The web and webstandards. اقرأ أيضًا الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث الحماية من مواقع الإنترنت في العالم الرقمي التأثير النفسي للألوان في تصميم الويب
-
سنبني خلال هذا المقال خط إنتاج Pipeline لنشر المشروع النموذجي الذي بدأناه في التمرين 11.2. إذ سننشئ نسخة خاصةً بنا من مستودع المشروع لكي نتعامل معها، ثم سنبني في آخر تمرينين خط إنتاج آخر لنشر بعض التطبيقات الخاصة بنا والتي بنيناها سابقًا. يضم القسم 21 تمرينًا من المفترض إكمالها جميعًا حتى تنهي هذا المنهاج، وعليك أن تسلم حلول هذه التمرينات إلى منظومة تسليم التمارين بنفس الأسلوب المُتبع في القسم السابق، إذ تُسلَّم التمرينات إلى نسخة مختلفة من المنهاج. ستعتمد المعلومات في هذا القسم على مفاهيم اطلعنا عليها سابقًا، لذلك ننصحك بإكمال الأقسام 0-5 قبل البدء بهذا القسم. لن تكتب الكثير من أسطر الشيفرة في هذا القسم، فهو يغطي في معظم الأوقات مواضيع عن التهيئة. وعلى الرغم من أن تنقيح الشيفرة صعب، لكن تنقيح أوامر التهيئة أصعب بكثير، فعليك إذًا التحلي بالصبر والمثابرة في هذا القسم. تجهيز التطبيقات لمرحلة الإنتاج ستضطر بعد الانتهاء من كتابة الشيفرة عاجلًا أم آجلًا إلى نقل تطبيقك إلى مرحلة الإنتاج، أي إلى مستخدميه الحقيقيين، ثم ستضطر بعدها إلى صيانة هذا التطبيق باستمرار وإصدار نسخٍ جديدة منه والعمل مع مطورين آخرين لتوسيعه. لقد استخدمنا حاليًا غيت هب GitHub لتخزين الشيفرة المصدرية، لكن ما الحل عندما نعمل ضمن فريق من المطورين؟ ستظهر عدة مشاكل عند تعاون عدة مطورين، فقد يعمل التطبيق جيدًا على حاسوبي، لكن قد يخفق على حواسيب مطورين آخرين يعملون على أنظمة تشغيل مختلفة، أو يستخدمون نسخًا مختلفة من المكتبات التي أدرجناها في التطبيق. يُشار إلى هذه المشكلة بالعبارة "التطبيق يعمل على جهازي works on my machine". هناك مشكلة أخرى، فلو أجرى مطورين تعديلات على شيفرة التطبيق ولم يتفقا من سينشر التعديلات التي أنجزها، من سيمنع أحدهما من محي تعديلات الآخر وكتابة تعديلاته مكانها؟ سنغطي في هذا القسم أساليب العمل المشترك لبناء ونشر التطبيقات بطريقة منضبطة ومحددة جيدًا، يظهر فيها بكل وضوح ما الذي سيحدث وتحت أية ظروف. بعض المصطلحات المفيدة نستخدم في هذا القسم مصطلحات قد لا تعرفها أو لم تفهمها جيدًا، سنناقش هذه المصطلحات تاليًا، وحتى لو كنت على دراية بهذه المصطلحات، اطلع على هذه الفقرة لنكون على وفاق في فهم المصطلح عند وروده. الفروع Branches يسمح نظام غيت Git بوجود نسخ، أو مسارات streams، أو إصدارات مختلفة من الشيفرة تتعايش معًا دون الحاجة لإلغاء بعضها بعضًا؛ فعندما تُنشئ مستودعًا سيكون هذا المستودع بمثابة الفرع الرئيسي (ندعوه في غيت بالاسم "main" أو "master"، لكن الأمر مختلف في المشاريع القديمة). لا بأس بهذا الأسلوب إذا كان هناك مطور واحد يستخدم هذا الفرع، ويعمل على تطوير ميزة واحدة للتطبيق كل مرة. سيكون استخدام الفروع مفيدًا عندما تتعقد بيئة التطوير، إذ سيعمل كل مطور على فرع أو أكثر، وسيمثل كل فرع نسخةً مختلفةً قليلًا عن نسخة الفرع الرئيسي. وعندما تكتمل الميزة التي يجري تطويرها في أحد الفروع ستُدمج مع الفرع الرئيسيٍ، وبالتالي ستصبح هذه التغييرات أو الميزات الجديدة جزءًا من التطبيق الرئيسي. وهكذا سيتمكن كل مطور من العمل على مجموعة من التعديلات بحيث لا يعيق بقية المطورين من العمل على أفكارهم الخاصة قبل إكمال هذه التعديلات. لكن ما الذي سيحدث لبقية الفروع الخاصة بالمطورين الآخرين عندما يدمج أحد المطورين تعديلاته ضمن الفرع الرئيسي؟ إذ سيبتعد بقية المطورين عن النسخة القديمة التي يعملون عليها. وكيف سيعرف المطورون أن تعديلاتهم التي يجرونها على النسخة السابقة ستكون متوافقةً مع الحالة الجديدة التي يفرضها دمج التعديلات ضمن الفرع الرئيسي؟ سنحاول الإجابة عن هذا السؤال الجوهري في هذا القسم. يمكنك الاطلاع على مزيدٍ من المعلومات حول الفروع من خلال قراءة المقالة "أساسيات التفريع (Branching) والدمج (Merging) في Git". طلبات السحب Pull requests يجري عادةً دمج فرع ضمن الفرع الرئيسي وفق آلية تُعرف بطلب السحب، أو كما يُعرف أحيانًا بالاختصار "PR"، إذ يطلب المطور الذي أجرى بعض التعديلات أن تُدمج التعديلات التي أجراها ضمن الفرع الرئيسي، وحالما يُقبل هذا الطلب أو يُفتتح للمراجعة، يمكن لمطور آخر أن يتحقق من أن كل شيء سيجري على مايرام بعد الدمج. لو اقترحت مثلًا تعديلًا على مادة منهجنا، فقد قدمت فعلًا طلب سحب. بناء التطبيق Build لهذا المصطلح معانٍ مختلفة في لغات البرمجة المختلفة. فلا حاجة في بعض اللغات المترجمة، مثل روبي Ruby، أو بايثون Python إلى خطوة بناء فعلية إطلاقًا. عندما نتكلم عن البناء عمومًا، فإننا نعني بذلك إعداد التطبيق ليعمل على المنصة التي صُمِّم لأجلها، وقد يعني ذلك، على سبيل المثال، أننا لو أردنا كتابة التطبيق بلغة TypeScript ثم تنفيذه على Node، فستكون خطوة البناء هي عملية نقل شيفرة TypeScript إلى جافا سكربت JavaScript. ستغدو هذه الخطوة إجبارية وأكثر تعقيدًا في اللغات المُصرَّفة، مثل C و Rust، إذ تتطلب شيفرتها التصريف إلى شيفرة قابلة للتنفيذ. وكنا قد اطلعنا في القسم 7 على برنامج webpack، وهو أداةٌ رائدة حاليًا في بناء نسخ إنتاج من تطبيقات React أو تطبيقات واجهة أمامية مكتوبة بلغة جافاسكربت JavaScript أو TypeScript. نشر التطبيقات Deploy يشير مصطلح "النشر" إلى وضع التطبيق في المكان الذي يمكن للمستخدم النهائي الوصول إليه واستخدامه؛ فقد يعني هذا المصطلح بالنسبة للمكتبات مثلًا وضعها ضمن حزم ثم دفعها إلى أرشيف للحزم (مثل npmjs.com) بحيث يمكن للمستخدمين إيجادها وتضمينها في مشاريعهم. تختلف صعوبة نشر خدمة (مثل تطبيق ويب) حسب تعقيدها، فقد اشتمل مخططنا لنشر التطبيق في القسم 3 مثلًا على تنفيذ بعض السكربتات يدويًا ثم دفع شيفرة المستودع إلى خدمة استضافة Heroku. سنطور في هذا القسم "خط إنتاج" لنشر كل جزء من شيفرتك آليًا إلى Heroku إن لم تسبب هذه الشيفرة أية مشاكل. وقد يكون النشر أحيانًا على درجة عالية من التعقيد خاصةً إذا تطلب التطبيق احتياجات خاصة، كأن يكون متاحًا دائمًا للعمل أثناء تطويره "لا إيقاف من أجل النشر zero downtime deployment"، أو كان علينا أن نأخذ في الحسبان بعض الأمور مثل نقل قواعد البيانات. لن نغطي النقاط المتعلقة بالنشر الذي يحمل تعقيدات مثل التي ذكرناها، لكن من المهم أن تدرك وجودها. ما هو التكامل المتواصل؟ يختلف المفهوم الدقيق لمصطلح التكامل المتواصل Continuous Integration -أو اختصارًا "CI"- عن كيفية استخدامه في مجال التطوير. ستجد نقاشًا قديمًا لكنه يحمل أثرًا كبيرًا عن استخدام هذا المصطلح في مدونة "مارتن فلور". وإذا أردنا التحديد الدقيق للمصطلح CI سنقول أنه يعني غالبًا "دمج التغييرات التي نفذها المطور مع الفرع الرئيسي" ثم أضافت ويكيبيديا Wikipedia العبارة "عدة مرات في اليوم" إلى المصطلح. وهذا الأمر صحيح عادةً، لكن عندما نشير إلى CI في مجال البرمجيات، فنحن نتحدث غالبًا عما سيحدث بعد عملية الدمج الفعلية للتغيرات، إذ قد نحتاج إلى إنجاز بعضٍ من هذه الخطوات: التدقيق lint: للحفاظ على الشيفرة واضحة وقابلة للصيانة. البناء build: وضع كل الشيفرة المُنجزة في برنامج واحد. الاختبار test: لضمان عدم إخفاق أية ميزات موجودة مسبقًا. التحزيم packaging: وضع كل ما نحتاجه في حزمة سهل الحمل والنقل. التحميل/ النشر deploy: لجعل البرنامج متاحًا للاستخدام. سنناقش كل خطوة من تلك الخطوات (عندما نجد فائدةً من ذلك) بشيء من التفصيل لاحقًا. وعلينا أن نتذكر دائمًا أنّ هذه العملية ستكون محددةً بدقة. يعيق التحديد الدقيق strict definition عادةً سرعة التطوير أو الإبداع في إيجاد الحلول، لكن من المفترض أن لا يكون هذا صحيحًا بالنسبة للتكامل المتواصل، إذ يجب وضع هذه القيود بطريقة مرنة تسمح بالتطوير والعمل المشترك. سيسمح استخدام أنظمة CI جيدة، مثل GitHub Actions الذي سنغطيه في هذا القسم بتنفيذ كل ما ذكرناه آليًا وبصورة سحرية. التحزيم والنشر مثل جزء من نظام التكامل المتواصل CI ينبغي التذكير من حين إلى آخر، أنّ عملية التحزيم وعملية النشر خاصة لا تُعدان أحيانًا جزءًا من نظام CI، لكننا سنعدّهما جزءًا من النظام، لأنه من المنطقي في العالم الحقيقي أن نضع كل الخطوات التي أشرنا إليها معًا. ويعود جزءٌ من ذلك للحفاظ على التسلسل في سياق العمل وخط إنتاج البرنامج (الطريق إلى إيصال المنتج إلى المستخدم النهائي)، بينما يعود الأمر في شقه الآخر إلى حقيقة أنّ هذه النقطة هي ما يسبب إخفاق العملية ككل. ستظهر المشاكل غالبًا في مرحلة التحزيم من نظام CI كونها مرحلةٌ لا تختبر محليًا، فمن المنطقي إذًا اختبار عملية تحزيم المشروع خلال سير العمل في CI حتى لو لم نضع هذه الحزمة موضع العمل، كما يمكن في بعض مسارات العمل أن نختبر حزمةً قد بُنيت فعلًا مسبقًا. سيؤكد ذلك أننا اختبرنا الشيفرة بنفس الشكل الذي سننشرها فيه خلال مرحلة الإنتاج. إذًا ما هو وضع عملية النشر؟ سنتحدث عن الاستمرارية وإمكانية التكرار مطولًا في الفصول القادمة، لكن تجدر الإشارة هنا إلى أننا نحتاج إلى عملية تبدو متماثلةً دائمًا، سواءٌ أجرينا الاختبارات في فرع تطوير أو في الفرع الرئيسي. نحتاج في الواقع إلى العملية نفسها "حرفيًا" بحيث يظهر الاختلاف فقط في نهايتها، وذلك عند تحديد ما إذا كنا في الفرع الرئيسي أم لا، وإن كنا نريد النشر أم لا. وفي هذا السياق من المنطقي تضمين خطوة النشر في سير عمل CI طالما أنها ستخضع للصيانة في نفس الوقت الذي نطورها فيه. يشير المصطلحان: "التسليم المتواصل Continuous Delivery" و"النشر المتواصل Continuous Deployment" -أو اختصارًا CD- إلى منظومة CI عندما تتضمن مرحلة النشر. لن نزعجك بالتعريف الدقيق، إذ يمكنك الاطلاع عليه من خلال Wikipedia، أو منشورات مدونة "مارتن فلور"، أو من خلال أكاديمية حسوب، لكننا نستخدم الاختصار CD ليشير إلى أسلوب ممارسة عملي يقتضي إبقاء الفرع الرئيسي متاحًا للنشر والتطوير في أي وقت. لكن ماذا عن المنطقة الغامضة بين مصطلحي CI وCD؟ فلو كان علينا مثلًا أن نجري بعض الاختبارات قبل أن ندمج أية شيفرات جديدة ضمن الفرع الرئيسي، هل نعد ذلك شكلًا من أشكال CI لأننا سنجري دمجًا متواصلًا مع الفرع الرئيسي؟ أم شكلًا من أشكال CD لأننا نتحقق بذلك أن الفرع الرئيسي قابلًا للنشر باستمرار؟ تقع بعض المفاهيم إذًا على الخط الفاصل بين المصطلحين، فمن المنطقي كما أشرنا سابقًا، أن نعد CD جزءًا من CI. لهذا السبب، سيُستخدم غالبًا المصطلح CI/CD للدلالة على العملية برمتها. وانتبه إلى أننا سنستخدم المصطلحين CI و CI/CD بالتناوب طوال الوقت في هذا القسم. أين تكمن أهمية استخدام نظام CI؟ لقد ذكرنا سابقًا مشكلة "يعمل على جهازي" ومشكلة نشر تغييرات متعددة المصادر، لكن ماذا عن بقية المشاكل؟ ماذا لو حملّت "سارة" الشيفرة مباشرةً إلى الفرع الرئيسي؟ ماذا لو استخدم "أحمد" فرعًا ولم يكلف نفسه عناء إجراء بعض الاختبارات قبل دمج ما عدّله ضمن الفرع الرئيسي؟ ماذا لو حاول "عبد الله" بناء نسخة إنتاج من التطبيق لكن بمعاملات خاطئة؟ سيمكِّننا استخدام التكامل المتواصل وفق طريقة منهجية في العمل في: منع رفع الشيفرات مباشرةً إلى الفرع الرئيسي. تنفيذ عملية CI لكل طلبات السحب إلى الفرع الرئيسي وتمكينها من دمج التغييرات. بناء حزم إنتاج للبرامج التي نطورها في بيئة معروفة تمتلك نظام CI. وهنالك أيضًا بعض الإيجابيات لتوسيع هذه الإعدادات: إذا استخدمنا CD في كل مرةٍ ننفذ فيها عملية دمج مع الفرع الرئيسي، سنكون واثقين من عمل الفرع الرئيسي وفق نظام الإنتاج. إذا سمحنا بإتمام عملية الدمج فقط في الحالة التي يكون فيها الفرع الرئيسي محدّثًا، سنضمن أن لا يلغي المطورون التغييرات التي نفذها غيرهم. تنبيه: سنفترض في هذا القسم أن الشيفرة الموجودة في الفرع الرئيسي ("mian" أو "master") ستعمل وفق نظام الإنتاج. ونظرًا لوجود عدد هائل من مخططات العمل (workflows) على git، قد يكون هناك على سبيل المثال حالات يظهر فيها فرع خاص للإصدار release branch يحتوي على الشيفرة التي تعمل وفق نظام الإنتاج. مبادئ هامة من المهم أن نتذكر أنّ CI/CD ليس هدفًا بحد ذاته، لكن الهدف هو تطوير أسرع وأفضل للتطبيقات بأقل عددٍ من الثغرات، وتحقيق أفضل تعاون بين المطورين. ولهذا لا بدّ من تهيئة نظام CI بما يلبّي المهمة التي ننفذها والمشروع بحد ذاته، كما ينبغي أن نبقي الهدف الرئيسي من استخدامه في حساباتنا دائمًا. يمكننا التفكير بنظام CI بمثابة جوابٍ على الأسئلة التالية: كيف سنتأكد أنّ جميع الاختبارات ستُطبّق على كامل الشيفرة التي ستُنشر؟ كيف سنضمن جاهزية الفرع الرئيسي للنشر في كل الأوقات؟ كيف سنتأكد أنّ النسخ التي تُبنى ستكون متوافقة، وستعمل دائمًا على المنصات التي صُمِّمت للنشر عليها؟ كيف سنضمن أن التغييرات الجديدة لن تلغي التغييرات الأقدم؟ كيف سننجز عملية النشر بضغطة زر أو بطريقة آلية، عندما يدمج مطور التغييرات التي أجراها مع الفرع الرئيسي؟ وهناك أيضًا دلائل علمية على الفائدة الهائلة التي يقدمها نظام CI/CD، فبناءً على دراسة واسعة في كتاب ": Building and Scaling High Performing Technology Organizations"، يقترن استخدام CI/CD بشدة مع النجاحات على صعيد المؤسسات (تحسين الأرباح وجودة المنتج وزيادة الحصة السوقية وتقليل زمن التسويق)، وكذلك من ناحية المطورين، فقد جعلتهم أكثر سعادةً وأقل إرهاقًا. سلوك موثق تشيع في أوساط المبرمجين طرفةٌ مفادها أنّ الثغرات هي "ميزات غير موثقة". لكن يجب علينا تفادي أية حالات لا نعلم تمامًا نتيجتها. فلو اعتمدنا مثلًا على عنوان طلب السحب لنحدد ما إذا كان إصدار البرنامج رئيسيًا major، أو ثانويًا minor، أو ترميميًا patch (سنتحدث عن معنى كل إصدار لاحقًا)، سيكون علينا الانتباه إلى الحالة التي يُغفل فيها المطور من وضع عنوانٍ لطلب السحب الذي قدمه. وماذا لو وضع هذا العنوان بعد بدء عملية البناء أو الاختبار؟ أو أنه غيَّر العنوان خلال مرحلةٍ ما، فما الذي سيكون عليه هذا الإصدار؟ من الممكن أن تغطي جميع الحالات التي قد تتوقعها، ومع ذلك، قد تظهر بعض الثغرات عندما يُنفّذ المطور شيئًا "إبداعيًا" لم تتوقعه إطلاقًا، فمن الجيد إذًا أن تنتهي العملية التي ستخفق بأمان في هذه الحالة. فلو عدنا إلى المثال السابق عندما يغير المطور عنوان الطلب أثناء تنفيذ عملية البناء. إذا لم نتمكن من توقع سيناريو مثل هذا مسبقًا، فمن الأفضل ربما أن تتوقف عملية البناء، وأن نبلِّغ المستخدم بأنّ شيئًا غير متوقع قد حدث، فنشر إصدار خاطئ سينتج حتمًا مشاكلًا أكبر، وسيكون إيقاف العملية وإخطار المستخدم هو الحل الأكثر أمانًا. يحدث الشيء ذاته في كل مرة قد نملك أفضل اختبارات لبرمجياتنا يمكن تخيلها، وقد تكون قادرةً على اصطياد أية مشكلة محتملة، لكنها ستبقى عديمة الجدوى إن لم ننفذها على الشيفرة قبل نشرها. علينا أن نضمن أنّ الاختبارات قابلةً للتنفيذ، كما نريد أن نضمن أنها ستعمل مع الشيفرة التي سننشرها فعليًا. فلن يفيدنا الاختبار الذي ينجح مثلًا ضمن فرع "سارة" ويفشل عند دمجه مع الفرع الرئيسي. وطالما أننا سننشر محتويات الفرع الرئيسي، لذا علينا أن نتأكد من نجاح الاختبارات على نسخة من الفرع الرئيسي بعد أن ندمج معه فرع "سارة". ستوصلنا المناقشة السابقة إلى مبدأ جوهري وهو التأكد أنّ السلوك نفسه سيحدث كل مرة، أو أنّ المهام المطلوبة ستُنفَّذ جميعها وبالترتيب الصحيح. يجب أن تبقى الشيفرة قابلة للنشر دائما إنّ وجود شيفرة قابلة للتوزيع والنشر دائمًا أمر مريح جدًا وخاصةً عندما يحتوي الفرع الرئيسي على شيفرة تعمل في وضع الإنتاج؛ فإذا ظهرت ثغرةٌ مثلًا وتطلب الأمر معالجتها، يمكنك سحب نسخة من الفرع الرئيسي (وهي الشيفرة التي تُنفًّذ في وضع الإنتاج) وحل المشكلة، ثم تقديم طلب سحب لإعادة الشيفرة إلى الفرع الرئيسي (دمج من جديد). ويجري هذا الأمر عادةً مباشرةً دون أية مشاكل. إذا اختلفت الشيفرة الموجودة في الفرع الرئيسي عن شيفرة الإنتاج ولم يكن الفرع الرئيسي قابلًا للنشر، سيكون عليك البحث عن الشيفرة التي تعمل في وضع الإنتاج وسحب نسخة عنها، ثم إيجاد الثغرة ومعالجتها، كما عليك إيجاد طريقة لإعادة الشيفرة إلى الفرع الرئيسي والعمل على نشر الجزء المحدد الذي أصلحته. لن يكون هذا الأمر مريحًا وستكون طريقة تنفيذه مختلفةً كليًا عن مخطط نشر التطبيقات الاعتيادي. معرفة أجزاء الشيفرة المنشورة- مجموع SHA/الإصدار من المهم غالبًا تحديد الشيفرة التي تعمل فعليًا في وضع الإنتاج. ولقد ناقشنا سابقًا أن شيفرة الفرع الرئيسي هي من تعمل في هذا الوضع في الحالة النموذجية، لكن هذا الأمر ليس ممكنًا دائمًا؛ فقد تتعرض عملية البناء للإخفاق عندما نحاول تشغيل شيفرة الفرع الرئيسي في وضع الإنتاج، وقد نجري عدة تغييرات على الشيفرة ونريدها أن تُنشر جميعها مباشرةً. ما نحتاج إليه في حالات مثل هذه (وهي فكرة جيدة عمومًا)، هو معرفة الشيفرة التي تعمل في وضع الإنتاج بالضبط؛ إذ يمكن معرفة ذلك أحيانًا عن طريق رقم الإصدار version، وأحيانًا بمجموع SHA sum (وهو جدول HASH يعرِّف بصورةٍ فريدة اعتماد git) متصل بالشيفرة. سنناقش موضوع تحديد رقم الإصدار لاحقًا في هذا القسم. الآلية الأكثر فائدةً هي ربط معلومات الإصدار مع تاريخ جميع الإصدارات، فلو اكتشفنا مثلًا وجود ثغرة في اعتماد محدد، يمكننا أن نعرف متى أُصدر هذا الاعتماد وكم عدد المستخدمين الذين تأثروا بالثغرة. وتظهر فائدة هذه المقاربة عندما تسبب الثغرة أخطاءً في بيانات قواعد البيانات، وهكذا من الممكن تقفي أثر البيانات الخاطئة بناءً على تاريخ إنشائها. أنماط إعدادات منظومة CI علينا تخصيص خادم منفصل لتشغيل مهام منظومة التكامل المتواصل CI لكي نلبي بعضًا من المتطلبات التي ذكرناها سابقًا، إذ سيقلل وجود خادم منفصل المخاطر الناتجة عن اختلاط عمليات أخرى بعملية منظومة CI/CD جاعلةً نتيجتها غير متوقعة. هنالك خياران: استضافة خادم خاص بنا أو الخدمة السحابية cloud service. استضافة Jenkins وإعدادات بيئة الاستضافة الذاتية self-host تُعد استضافة Jenkins الخيار الأكثر شعبيةً من بين خيارات الاستضافة الذاتية، فهي مرنةٌ جدًا وتمتلك عدة إضافات plugin لكل شيء تقريبًا (ماعدا الشئ الوحيد الذي تريده). تمثل هذه الاستضافة خيارًا جيدًا للعديد من التطبيقات. يعني استخدام الاستضافة الذاتية أن تكون بيئة الاستضافة تحت سيطرتك بالكامل، وكذلك جميع الموارد، ولن تكون أسرارك عرضةً للكشف من قبل الآخرين، كما ستتمكن من فعل ما تشاء بالعتاد الصلب. لكن ولسوء الحظ هناك جانبٌ مظلم لاستضافة Jenkins فهي صعبة الإعداد، إذ تتطلب المرونة الكبيرة في الإعداد وجود العديد من قوالب template الشيفرة التي تتطلب الإعداد ليعمل كل شيء، ويتطلب استخدام Jenkins بالتحديد إعداد منظومة CI/CD باستخدام لغة Jenkins الخاصة بالنطاق domain-specific. ولا ننس مخاطر إخفاق العتاد الصلب والذي قد يسبب مشكلةً في حالات الازدحام. تعتمد فاتورة الاستضافة الذاتية على العتاد الصلب الذي تختاره غالبًا، فأنت تدفع مقابل الخادم وما ستفعله على الخادم لن يغير من فاتورتك. استخدام GitHub Actions وحلول أخرى معتمدة على الاستضافة السحابية لن تضطر للتفكير كثيرًا عند إعداد بيئة الاستضافة في الاستضافة السحابية، فكل ما عليك فعله هو أن تطلب من الاستضافة ما تريده، ويتضمن ذلك عادةً وضع ملف في مستودعك (ثم إخبار منظومة CI بقراءته)، أو التحقق من وجود ملف كهذا في المستودع. سيكون ملف تهيئة CI في الاستضافة السحابية أبسط قليلًا، وخاصةً إن لم تتعدّى الحدود "الطبيعية" للاستخدام، لكن قد تغدو خيارات هذه الإستضافة محدودةً قليلًا إن أردت فعل أشياء خاصة بين الفينة والأخرى، أو قد تجد صعوبةً في ذلك، خاصةً في إنجاز مهام محددة لم تُبنى المنصة السحابية لكي تنجزها. سنركز في هذا القسم على الاستخدامات التي تعد "طبيعية"، فقد تتطلب إعدادات بعض المهام الخاصة عتادًا صلبًا خاصًا على سبيل المثال. وبعيدًا عن إعدادات التهيئة التي ذكرناها سابقًا، قد تواجهنا مشاكلًا تتعلق بمحدودية الموارد على الاستضافة السحابية، فلو بدت النسخة بطيئة على الاستضافة الذاتية، يمكنك ببساطة حجز خادم أقوى وتضع ما تحتاجه من الموارد ضمنه، لكن هذا الأمر قد يكون مستحيلًا في الاستضافة السحابية. ستعمل العقد التي تبنيها في GitHub Actions مثلًا على معالجين افتراضيين (vCPU) و8 جيجابايت من ذواكر الوصول العشوائي. ستعتمد فاتورتك في الاستضافة السحابية على الوقت المستغرق في بناء تطبيقك، وهذا أمر يجدر أخذه بالحسبان. لماذا نفضل خيارا على آخر؟ إن كان مشروعك صغيرًا إلى متوسط الحجم ولن يحتاج أية متطلبات خاصة (مثل الحاجة إلى بطاقة رسومية لتنفيذ الاختبارات)، ستكون الاستضافة السحابية الحل المناسب غالبًا، إذ ستكون الإعدادات بسيطةً ولن تدخل دوامة إعدادات النظام الخاص بك، كما ستكون الكلفة أقل للمشاريع الصغيرة خاصة؛ أما بالنسبة للمشاريع الأضخم والتي تحتاج إلى موارد أكبر أو بالنسبة للشركات الكبيرة التي تضم عدة فرق للتطوير وعدة مشاريع، قد يكون اختيار منظومة استضافة ذاتية هو الخيار الأنسب. لماذا استخدمنا GitHub Actions في هذه السلسلة؟ يُعدّ GitHub Actions الخيار الأنسب كوننا نستخدم غيت هب GitHub، إذ سيؤمن لنا منظومة CI قوية تعمل مباشرةً دون الحاجة إلى إعداد خادم أو خدمة سحابية يؤمنها طرف ثالث. إضافةً إلى سهولة استخدامه، يُعد GitHub Actions خيارًا جيدًا من عدة جوانب، فقد يكون أفضل خدمة سحابية موجودة حتى اللحظة، إذ يحظى بشعبية كبيرة منذ إصدار النسخة الأساسية منه في نوفمبر (تشرين الثاني) عام 2019. التمرين 11.1 قبل أن ننغمس في إعداد خطوط إنتاج لأنظمة CI/CD، لا بدّ من مراجعة ما قرأناه. لنتهيأ للانطلاق فكر بحالة افتراضية نكون فيها أمام تطبيق يجري تطويره من قِبل فريق من 6 مطورين وسيصدر قريبًا. لنفترض أنّ اللغة المستخدمة في تطوير التطبيق ليست JavaScript/TypeScript فلنقل Python، أو Java، أو Ruby، أو أية لغات قد تفكر بها. اكتب موضوعُا بسيطًا من 200-300 كلمة تجيب فيه أو تناقش النقاط التي سنطرحها تاليًا. يمكنك التحقق من عدد الكلمات التي تكتبها عبر موقع wordcounter. خزّن إجابتك في ملف اسمه "exercise1.md" في جذر المستودع الذي ستنشئه في التمرين 11.2 ناقش النقاط التالية: بعض الخطوات الشائعة في إعداد CI بما فيها التدقيق والاختبار والبناء، وكذلك الأدوات اللازمة لتنفيذ هذه الخطوات في بيئة عمل اللغة التي تختارها. يمكنك البحث عن الأجوبة عبر غوغل Google. ما هي بدائل إعداد منظومات CI عن GitHub Actions أو Jenkins؟ يمكنك الاستعانة بمحرك البحث غوغل. أين سيكون تطبيق هذه الإعدادات أفضل، على استضافة ذاتية أو استضافة سحابية؟ لماذا؟ ما هي المعلومات التي ستحتاجها لاتخاذ قرارك؟ تذكر أنه لا توجد إجابات صحيحة أو خاطئة لجواب هذا السؤال. ترجمة -وبتصرف- للفصل Introduction to CICD من سلسلة Deep Dive Into Modern Web Development اقرأ أيضًا ما هو Git إعادة تأسيس تفريعات طلب السحب وتحديثه في git إعداد التكامل المستمر والنشر المستمر باستخدام الخدمتين CircleCI وCoveralls التكامل المستمر: تثبيت Concourse CI على أوبنتو
-
يشرح هذا المقال مفاهيم تصميمية أساسية تتمثل بسهولة أو إمكانية الوصول accessibility إلى محتوى مواقع ويب وكيفية تصميم مواقع ويب يستطيع معظم زائريها الحصول على محتواها بسهولة ومتعة. تسهيل وصول جميع المستخدمين إلى مواقع ويب لن يتمكن بعض الزائرين من تجربة موقعك بالطريقة التي تأملها نظرًا لمعوقات فيزيائية أو تقنية قد تعترضهم. لذلك سنناقش في هذا المقال المبادئ العامة لسهولة الوصول accessibility (تترجم أحيانًا إلى شمولية أي شمولية التصميم لكل المستخدمين) وسنشرح بعض القواعد المتعلقة بها. المبادئ العامة لسهولة الوصول قد نربط إمكانية الوصول في البداية بالمعوقات السلبية مثل قولنا بأنّ الوصول إلى هذا البناء ممكن عندما تُعتمد مجموعة قواعد ناظمة مثل عرض الباب أو حجم المرافق الصحية أو موقع المصعد، وهذه مقاربة ضيقة لمفهوم إمكانية أو سهولة الوصول، وفكِّر بالأمر على أساس طريقة مميزة لدعم الآخرين ولخدمة العملاء، فما الذي قد يستفيده الناس في البرازيل من موقعك الذي يعتمد اللغة الإنكليزية؟ هل يمكن لمستخدِمي الهواتف الذكية تصفح مواقع ويب مزدحمة ومخصصة لشاشات الحواسب المكتبية الواسعة والتي تستخدِم حزمة استهلاك بيانات غير محدودة؟ بالطبع سيغادر الزوار موقعك في حالات مثل هذه، إذ ينبغي التفكير عمومًا بالمنتج الذي تقدِّمه انطلاقًا من وجهات النظر المختلفة لجميع العملاء المستهدَفين ومن ثم التكيف معها، فهذه هي سهولة الوصول. سهولة الوصول في عالم ويب تعني سهولة الوصول في سياق عالم ويب قدرة الجميع على الوصول إلى المحتوى الذي تقدِّمه دون النظر إلى الإعاقة التي يعانيها الزائر أو مكانه أو أية محدودية تقنية قد يواجهها أو أية ظروف أخرى. لنتأمل مقطع فيديو: حالة ضعف السمع: كيف يمكن لشخص لديه تدهور في حاسة السمع الاستفادة من مقطع الفيديو؟ لا بدّ إذًا من تزويد الفيديو بالكلمات أو تقدّم نص الفيديو بأكمله، وتأكد أيضًا من قدرة المستخدِم على ضبط مستوى الصوت بما يلبي احتياجاته الخاصة. حالة ضعف البصر: قدّم أيضًا نص الفيديو بأكمله لكي يطَّلع المستخدِم على المضمون دون أن يشغِّله، كما يمكنك تقديم وصفًا صوتيًا لما يحدث في الفيديو. إمكانية التوقف المؤقت: قد لا يفهم المستخدِم ما تقوله إحدى الشخصيات في الفيديو، لذلك من الأفضل تقديم إمكانية إيقاف المقطع مؤقتًا ليتسنى له قراءة كلماته أو إدراك ما يجري. إمكانية استعمال لوحة المفاتيح: لكي يتمكن المستخدِم من الوصول إلى الفيديو أو الخروج منه وتشغيله وإيقافه دون أن يعلق داخله. تتضمن أساسيات سهولة الوصول في ويب أشياءً مثل: ضع دائمًا نصًا بديلًا للصورة للمستخدِمين الذين يعانون من مشاكل بصرية أو لمن لديه اتصال ضعيف بالإنترنت عندما يحتاج الموقع إلى صورة لنقل معنى معين. تأكد من إمكانية تشغيل جميع المستخدِمين لبعض الواجهات الرسومية مثل عرض القوائم بنقرة زر واحدة أي لمسة أو ضغطة على زر "Return" مثلًا. حدِّد بصراحة لغة المحتوى الذي تعرضه لكي تتمكن البرمجيات التي تقرأ محتوى الشاشة من قراءة النصوص بصورة صحيحة. تأكد من قدرة المستخدِم على التنقل بين الأدوات التي تعرضها الصفحة من خلال لوحة المفاتيح فقط دون أن يعلق ضمنها، أي القدرة على الدخول والخروج على الأقل. وهذه النقاط هي البداية فقط. أدارت منظمة W3C منذ عام 1999 مجموعة عمل تُدعى "مبادرة سهولة الوصول على الويب Web Accessibility Initiative" لتطوير معايير إمكانية الوصول من خلال الإرشادات والمواد الداعمة والموارد على المستوى العالمي، ويمكنك الاطلاع على المزيد من خلال موقع المبادرة WAI، كما قد تجد بعض الأفكار في مقالات أكاديمية حسوب. تصميمات موجهة لجميع المستخدمين عندما تشرع في تصميم موقع ويب ينبغي علينا التفكير أولًا بتصميم شمولي Universal Design للموقع يلائم جميع مستخدِميه بغض النظر عن أية إعاقات قد يعانونها أو أية قيود تقنية أو ثقافية أو مكانية. يناقش هذا المقال بعض الأفكار السريعة والناجحة في تصميم أكثر شمولية لمواقع ويب، ولكن لا بدّ أن تكون أولًا على دراية بمفهوم التصميم الشمولي Universal design. التلاؤم اللوني من الأمور المهمة التي تجعل النصوص في مواقع ويب مقروءة هو استخدام خلفية ذات لون ملائم تسهل متابعة النص، إذ سيساعد ذلك مَن يعاني من إعاقة بصرية أو من يستخدِم هاتفه الذكي للقراءة في الخارج وعلى الطرقات. تُحدِّد منظمة W3C التلاؤم اللوني من خلال خوارزمية تحسب نسبة السطوع luminosity ratio بين الخلفية والواجهة، وقد تكون هذه الحسابات معقدةً، لكن بعض الأدوات الجاهزة قد تساعدنا في إنجاز الأمر. اختُبر التلاؤم اللوني لصفحة المقال الأصلي في الصورة السابقة وأعطى نتيجة 8.30:1 وهذا الرقم أعلى بكثير من الحد الأدنى المقبول الذي يقدَّر بالنسبة 4.5:1 وبالتالي لا بد أن يساعد التلاؤم اللوني للصفحة الكثيرين من ذوي الإعاقة البصرية في قراءتها. حجم خط الكتابة يمكنك تحديد حجم خط الكتابة في موقع ويب بوحدات قياس نسبية relative أو مطلقة absolute. وحدات القياس المطلقة لا تُحسَب هذه الوحدات حسابًا تناسبيًا، وإنما تعتمد على حجم محدد بصورة أساسية في الحساب، إذ تُقدَّر وحدة القياس المطلقة غالبًا بالبيكسل px، فإذا وضعت الشيفرة التالية مثلًا في ملف تنسيق CSS: body { font-size:16px; } فأنت تطلب من المتصفح أن يكون حجم الخط 16 بيكسل دائمًا، وقد تلتف بعض المتصفحات الحديثة على هذه القاعدة متظاهرةً أن حجم الخط سيكون 16 بكسل عندما يكون معامل تكبير الصفحة 100%، أي الحجم الطبيعي، ومع هذا وعلى امتداد سنوات عدة فقد عرض إنترنت إكسبلورر عمدًا الخطوط التي ضُبط حجمها على 16 بكسل مثلًا بالحجم 16 بكسل تمامًا بغض النظر عن معامل التكبير وصولًا إلى النسخة 8 التي لا بد من الانتباه لها لأنها لاتزال مستخدَمة. وحدات القياس النسبية تُحسَب هذه الأحجام نسبةً إلى العنصر الأب، وهي أكثر وضوحًا فيما يخص سهولة الوصول لأنها تحترم الإعدادات الخاصة بنظام المستخدِم، كما يُعبَّر عن الوحدات النسبية بالرموز em و% وrem: الحجم المبني على النسبة المئوية %: تخبر هذه الوحدة المتصفح أنّ حجم الخط في العنصر هو نسبة مئوية من حجم الخط في العنصر الأب الذي حُدِّد فيه حجم الخط، فإذا لم يكن للعنصر أب، فستجري الحسابات بالنسبة إلى حجم الخط الافتراضي للمتصفح (16 بكسل عادةً). الحجم المبني على الوحدة Em: تُحسَب اعتمادًا على أسلوب النسبة المئوية ذاته لكن على أساس أجزاء من 1 وليس 100، كما يُقال أن "em" هو عرض الحرف الأبجدي "M" على أساس حرف كبير (إذ يمكن وضعه ضمن مربع بصورة تقريبية). الحجم المبني على الوحدة rem: تُحسَب على أساس نسبة من حجم الخط للعنصر الجذري، ويعبَّر عنها على أساس أجزاء من 1 كما هو حال Em. لنفترض أننا نريد حجمًا أساسيًا للخط مقداره 16 بكسل وحجمًا مقداره 32 بكسل لعنصر العنوان الرئيسي h1، فإذا وجدنا ضمن العنصر h1 الوسم span الذي يطبق تنسيق الصنف subheading، فيجب تصيير ما داخل span أيضًا بالنسبة إلى حجم الخط الافتراضي (16 بكسل عادة)، وإليك شيفرة HTML لتوضيح الفكرة: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Font size experiment</title> </head> <body> <h1>This is our main heading <span class="subheading">This is our subheading</span> </h1> </body> </html> أما شيفرة CSS المبنية على النسبة المئوية: /* 100% من حجم الخط الأساسي للمتصفح والذي يكون عادة 16 بكسل */ body { font-size:100%; } /* أي حوالي 32 بكسل body ضعفي حجم المحدد */ h1 { font-size:200%; } /* أي العودة إلى القياس 16 بكسل h1 نصف */ span.subheading { font-size:50%; } سنواجه المشكلة نفسها عند استخدام وحدة القياس Em: /* 1em = 100% من قياس الخط الأساسي الذي يكون عادة 16 بكسل*/ body { font-size:1em; } /*أي حوالي 32 بكسل body ضعفي حجم المحدد */ h1 { font-size:2em; } /* أي العودة إلى القياس 16 بكسل h1 نصف */ span.subheading { font-size:0.5em; } لاحظ كيف ستغدو الحسابات مزعجةً إذا أردت ملاحقة العنصر الأب ثم أب الأب وهكذا، كما تُنفّذ معظم التصاميم على برمجيات تستخدِم البكسل، لذلك من الأفضل أن تجري الحسابات من قِبَل الشخص الذي كتب شيفرة CSS تقاس الوحدة rem بالنسبة إلى حجم العنصر الجذري وليس لأيّ عنصر أب، لذلك يمكن كتابة تنسيق CSS كما يلي: /* 1em = 100% من قياس الخط الأساسي الذي يكون عادة 16 بكسل*/ body { font-size:1em; } /*أي حوالي 32 بكسل body ضعفي حجم المحدد */ h1 { font-size:2rem; } /*الحجم الأصلي*/ span.subheading { font-size:1rem; } يبدو الأمر أسهل، أليس كذلك؟ يعمل هذا التنسيق على إنترنت أكسبلورر 9 وغيره من المتصفحات الحالية، لذلك يعود اختيار وحدة القياس لك بالمطلق. لماذا قد أستخدم وحدات القياس النسبية لأنك لا تعرف متى سيرفض المتصفح تكبير أو تصغير حجم النص الذي يعتمد البيكسل على أساس وحدة قياس، كما أنّ موقعك قد يتلقى زيارات ممن يستخدِمون متصفحات قديمةً، لذلك سنقدِّم لك النصائح التالية: استخدم وحدة القياس rem وستكون النتائج مرضيةً في جميع المتصفحات. دع مهمة عرض الخطوط في المتصفحات القديمة لمحركاتها الداخلية، إذ تتجاهل هذه المحركات أيّ خاصية أو قيمة لتنسيقات CSS لا تتوافق معها، وهكذا ستبقى قادرًا على عرض صفحتك على تلك المتصفحات، وعلى أية حال، ستختفي المتصفحات القديمة مع الوقت حتى لو لم يتفق ذلك مع رؤية المصمم. حجم السطر هنالك جدل طويل قائم حول طول الأسطر في ويب، وإليك القصة كاملةً. لقد أدرك العاملون في مجال الطباعة مع ظهور المجلات المطبوعة أن أعين القراء ستعاني عند الانتقال من سطر لآخر إذا كان السطر طويلًا جدًا، وكان الحل هو ظهور الأعمدة، ولم يتغير الأمر كثيرًا عندما انتقلنا إلى عالم الويب، ولا تزال أعين القراء تلاحق الأسطر، لذلك كان الحل بتحديد حجم السطر ليضم ما بين 60 إلى 70 محرفًا فقط لتسهيل الأمر على القارئ، إذ يمكنك لإنجاز الأمر تحديد حجم العنصر الذي يحتوي على النص، وإليك شيفرة HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Font size experiment</title> </head> <body> <div class="container"> <h1>This is our main heading <span class="subheading">This is our subheading</span> </h1> <p>[lengthy text that spans many lines]</p> </div> </body> </html> لدينا عنصر div له صنف التنسيق container، إذ يمكننا تنسيق div بضبط عرضه باستخدام الخاصية width أو من خلال ضبط عرضه الأعظمي لكي لا يزداد كثيرًا باستخدام الخاصية max-width، فإذا أردت موقعًا مرنًا أو متجاوبًا ولم تكن تعرف العرض الافتراضي الذي يأخذه المتصفح، فيمكنك استخدام الخاصية max-width لكي تضبط عدد المحارف في السطر بحدود 70 محرفًا لا أكثر: div.container { max-width:70em; } النصوص البديلة عن الصور والمقاطع الصوتية ومقاطع الفيديو تضم مواقع الويب أشياء أخرى غير النصوص، ولا بد من الانتباه إليها: الصور قد تكون الصور لمجرد العرض وتدعى بالصور الاستعراضية أو قد تحتوي على معلومات، لكن لا ضمانة بأن يراها المستخدِم لأسباب منها: استخدام ذوي الإعاقة البصرية قارئات الشاشة التي تتعامل مع النصوص فقط. استخدام شبكات إنترانت محلية تفرض قيودًا على عرض الصور من مصادر خارجية أو شبكات توريد محتوى CDN. تعطيل المستخدِم عرض الصور لتوفير حزمة البيانات المتاحة وخاصةً عند استخدام الهواتف الجوالة. أما الصور الاستعراضية Decorative، فتُستخدَم لتزيين الصفحات ولا توصل أية معلومات حقيقة، كما يمكن استبدالها في معظم الحالات بصورة خلفية، وتأكد من وضع نص فارغ على أساس قيمة للسمة alt في عنصر الصورة كي لا يتجاهل المتصفح عرض النص البديل. <img src="deco.gif" alt=""> وأما الصور التي تحتوي على معلومات Informative، فتُستخدَم لإيصال معلومات محددة، مثل عرض رسم بياني أو وجه أحد ما أو أية معلومات أخرى، إذ عليك أن تقدِّم على الأقل نصًا بديلًا في هذه الحالة (السمة alt)، فإذا أمكن وصف الصورة جيدًا، فيكفي استخدام النص البديل، وإلا عليك تقديم محتوى الصورة تقديمًا آخرًا في الصفحة نفسها مثل أن تعرض بالإضافة إلى الرسم البياني جدولًا يضم المعلومات نفسها، أو الجأ إلى السمة longdesc التي تحمل عنوان URL يشير إلى مصدر يشرح صراحةً محتوى الصورة. الصوت والصورة لابد أن تقدِّم بديًلا عن الوسائط السمعية والبصرية أيضًا. ترجمة الفيديو أو عرض كلماته: لا بد من إضافة كلمات الفيديو لمساعدة الزوار ذوي الإعاقة السمعية أو الذين لا يمتلكون مكبرات صوتية أو من يعمل في بيئات صاخبة. تقديم نص الفيديو أو الملف الصوتي كاملًا: سيكون عرض الكلمات أثناء تشغيل الفيديو ممتازًا لمن لديه الوقت لمتابعته، لكن قد لا يتمكن العديد من الزوار من ذلك، بالإضافة إلى اعتماد محركات البحث على النصوص لفهرسة المحتوى، لذلك من الأجدى تقديم نصوص كاملة توضِّح ما يقال في الفيديو أو في المقطع الصوتي. ضغط الصور عندما يرغب الزائر في عرض الصور على المتصفح لكنه يعاني من محدودية في حزمة تراسل البيانات وخاصةً في البلدان النامية وعلى أجهزة الهاتف المحمول، لذلك اضغط الصور على موقعك إذا كنت تريده ناجحًا، وستجد العديد من الأدوات التي تساعدك في ذلك: برمجيات تُثبَّت على جهازك: ستجد ImageOptim على ماك، وستجد PNGcrush على دوس ولينوكس ويونكس، بينما يعمل OptiPNG على كل المنصَّات. أدوات على الإنترنت: مثل smushit! من ياهو Yahoo و Online Image Optimizer من Dynamic Drive، إذ يحوِّل هذا الأخير الصور تلقائيًا من تنسيق إلى آخر إذا كان أكثر فعاليةً فيما يخص تخفيض استهلاك حزمة تراسل البيانات. نظرة إلى ميزات HTML التي تدعم سهول الوصول هنالك مجموعة من الميزات الخاصة في HTML قد تسهل وصول الأشخاص ذوي الإعاقة إلى محتوى صفحة ويب، وسنستعرض بعضها في هذه الفقرة. التنقل عبر المفتاح TAB يمكن للزائرين الذين لا يمتلكون أجهزة تأشير مثل الفأرة، أو لا يستطيعون استخدامها التنقل عبر الروابط من خلال استخدام المفتاح TAB، إذ ينبغي أن تكون الروابط مرتبةً بطريقة منطقية لاستخدام هذه الميزة، لذلك تقدِّم HTML السمة tabindex التي تحدِّد الترتيب، فإذا كانت شيفرة HTML المكتوبة خطيةً ومتتابعةً كما ينبغي، فستظهر الروابط وفق الترتيب المنطقي تلقائيًا. <ul> <li><a href="here.html" tabindex="1">Here</a></li> <li><a href="there.html" tabindex="3">There</a></li> <li><a href="anywhere.html" tabindex="2">Anywhere</a></li> </ul> تعرض الشيفرة السابقة التي قدمناها لمجرد توضيح الفكرة ترتيب استخدام TAB من "Here" إلى "Anywhere" إلى "There". عناوين الروابط إذا لم يشرح الرابط نفسه بنفسه، أو كان من الأفضل شرح وجهة الرابط بتفاصيل أكثر، فيمكنك إضافة معلومات عن الرابط باستخدام السمة title. <p>I'm really bad at writing link text. <a href="inept.html" title="Why I'm rubbish at writing link text: An explanation and an apology.">Click here</a> to find out more.</p> مفاتيح الوصول تزوِّد مفاتيح الوصول Access keys المستخدِم بطريقة سهلة للتنقل بتعيين اختصار إلى الرابط عبر لوحة المفاتيح، إذ يتلقى الرابط التركيز عندما يضغط المستخدِم Ctrl أو Alt مع مفتاح الوصول، وتختلف مجموعة الأزرار التي تُضغَط معًا من نظام لآخر. <a href="somepage.html" accesskey="s">Some page</a> روابط التجاوز تعمل روابط التجاوز Skip Links على أساس رديف للتنقل عبر المفتاح TAB، إذ تسمح بالقفز إلى جزء محدَّد من الصفحة، فقد يرغب أحد الزوار بتجاوز الكثير من الروابط إلى المحتوى الرئيسي بدلًا من التنقل من رابط لآخر حتى الوصول إلى المطلوب. <header> <h1>The Heading</h1> <a href="#content">Skip to content</a> </header> <nav> <!-- navigation stuff --> </nav> <section id="content"> <!--your content --> </section> ترجمة -وبتصرف- للمقال ?What is accessibility، والمقال ?How can we design for all types of users، والمقال ?What HTML features promote accessibility. اقرأ أيضا الفرق بين إمكانية الوصول والشمولية في تصميم تجربة المستخدم سهولة وصول جميع الزوار لمواقع وتطبيقات الويب التحقق من سهولة الوصول لصفحات الويب المبادئ الخمسة الأساسية في قابلية الاستخدام إعداد صور متجاوبة في صفحات الويب
-
انصب تركيزنا في هذا القسم على بناء منظومة تكامل مستمر CI بسيطة وفعالة ومحكمة، تساعد المطورين على العمل معًا والحفاظ على جودة الشيفرة ومن ثم نشرها بأمان. ما الذي يمكننا فعله أكثر؟ لنتذكر أنه في العالم الحقيقي ستمتد أيادٍ إلى الكعكة غير أياد المطورين والمستخدمين. حتى وإن لم يكن ذلك صحيحًا، وخاصة بالنسبة للمطورين، إلا أنّ هناك الكثير الذي تقدمه منظومة CI غير ما اطلعنا عليه. مجال الرؤية والفهم في جميع الشركات ما عدا الصغيرة منها، لا تُتخذ القرارات حول تطوير المنتجات حصرًا من طرف المطورين. يشير مصطلح أصحاب الشأن "stakeholder" إلى الأشخاص داخل وخارج فريق التطوير، الذين لديهم مصلحة في مراقبة تقدم عملية التطوير.عند هذا المستوى، هناك غالبًا تكاملٌ بين git وأي برنامج لإدارة المشاريع أو تتبع الثغرات قد يستخدمه الفريق. يُعد امتلاك مرجع إلى نظام التتبع في طلبات السحب أو في الشيفرة المعتمدة أكثر الطرق شيوعًا لتنفيذ ذلك. وهكذا، عندما تعمل على النقطة رقم 123 مثلًا، بإمكانك عندها تسمية طلب السحب الخاص بك BUG-123: Fix user copy issue، وسيلاحظ نظام تتبع الثغرات عندها الجزء الأول من اسم طلب السحب، وسينقل النقطة إلى قائمة النقاط المنفَّذة Done عندما يُدمج الطلب. تنبيهات عندما تنتهي عملية CI بسرعة، فمن المناسب أن نراقب العملية فقط وننتظر النتائج، لكن مع ازدياد حجم المشاريع ستزداد أيضًا فترة تنفيذ عمليات بناء واختبار الشيفرة. سيقودنا ذلك إلى الحالة التي تستغرق فيها ظهور نتائج بناء الشيفرة وقتًا طويلًا، مما يدفع المطور للتفكير في العمل على مهمة أخرى، وهذا سيقود بدوره إلى نسيان عملية البناء. ستظهر المشكلة في طرحنا هذا خاصة عندما نتحدث عن دمج طلبات السحب التي قد تؤثر على عمل مطور آخر، إما بالتسبب بمشاكل في عمله أو تأخير هذا العمل. وقد يقودنا ذلك أيضًا إلى الحالة التي تعتقد فيها أنك نشرت شيئًا، لكنك في الواقع لم تنهي عملية النشر، وسيؤدي ذلك إلى سوء التواصل مع أعضاء فريقك أو مع الزبائن (كأن تقول: "جرب من جديد، لا بدّ أنّ المشكلة قد حُلَّت"). هناك عدة أساليب لحل هذه المشكلة، تتدرج من إنشاء تنبيهات بسيطة إلى عمليات أكثر تعقيدًا تدمج ببساطة الشيفرة التي تمرر إليها إن تحققت جملةٌ من الشروط الموضوعة مسبقًا. سنناقش حاليًا التنبيهات مثل حل بسيط، كونها الوحيدة التي تتعلق بسير مخطط عمل الفريق. يرسل غيت هب افتراضيًا بريدًا إلكترونيًا عند إخفاق البناء. يمكن تغيير ذلك لإرسال تنبيهات بغض النظر عن حالة البناء، كما يمكن تهيئته لإنذارك على واجهة ويب غيت هب GitHub. طبعًا هذا الأمر رائع، لكن ماذا لو أردنا أكثر من ذلك؟ ماذا لو لم يعمل هذا الحل لسببٍ ما مع حالتنا؟ يمكن أن يتكامل غيت هب GitHub مع عدة تطبيقات رسائل مثل Slack لإرسال التنبيهات، وستكون هذه التطبيقات قادرةً على تحديد متى ترسل هذه التنبيهات بناءً على منطق يفرضه غيت هب GitHub. التمرين 11.18 أعددنا قناة fullstack_webhookعلى مجموعة Discord على العنوان "https://study.cs.helsinki.fi/discord/join/fullstack" لاختبار تكامل منظومة الرسائل. ستحتاج طبعًا إلى بريد إلكتروني للتسجيل، وانتبه إلى ضرورة استخدام عنوان خطاف الويب webhook الخاص بالتطبيق Discord لتنفيذ هذا التمرين. ستجد هذا الخطاف في الرسالة المنبثقة القناة "fullstack_webhook". ويُستحسن عدم الالتزام بالخطاف على غيت هب GitHub. أفعال لتنبيه المستخدم إلى نجاح أو فشل البناء ستجد العشرات من أفعال GitHub Actions التي طورها مطورون مستقلون على GitHub Action Marketplace بمجرد أن تبحث عن العبارة discord. اختر واحدًا لتستخدمه في هذا التمرين. وقد اخترنا discord-webhook-notify لأنه حصل على تقييم مرتفع وله توثيق جيد. هيئ الفعل بحيث يعطي نوعين من التنبيهات: مؤشر على النجاح إن نُشرت النسخة. مؤشر على الفشل إن أخفق البناء. في حال وقوع خطأ، لا بدّ أن تكون رسالة الخطأ مسهبة لمساعدة المطور على إيجاد الخطأ بسرعة وإيجاد الشيفرة المعتمدة التي سببت هذا الخطأ. ابحث في توثيق GitHub عن كيفية التحقق من حالة المهمة. يمكن أن تبدو التنبيهات على النحو التالي: المقاييس Metrics لقد أشرنا في الفقرة السابقة أنه عندما ينمو المشروع ستزداد مدة إنجاز خطوات البناء والاختبار، وهذا ليس بالأمر المثالي، فكلما طالت حلقة وصول النتائج ستصبح دورة التطوير بطيئة. وعلى الرغم من إمكانية القيام بأشياء لتقليل الوقت اللازم للبناء، من المفيد أيضًا أن ننظر جيدًا إلى الصورة الكلية للوضع. فمن الجيد أن نعرف كم استغرقت عملية البناء قبل أشهر عدة موازنةً مع ما تستغرقه الآن. هل يسلك الاختلاف منحًى خطيًا أم يظهر على هيئة قفزات فجائية؟ كما أنّ معرفة السبب الكامن خلف زيادة زمن البناء سيساعدنا جدًا في حل المشكلة؛ فإذا زاد زمن التنفيذ على نحوٍ خطي من 5 إلى 10 دقائق خلال سنة، فيمكننا أن نتوقع بأنه سيزداد أيضًا بضع دقائق خلال عدة أشهر قادمة ليصل إلى 15 دقيقة، وستكون لدينا فكرةً عن قيمة ما ننفقه من وقت لتسريع عمل منظومة CI. يمكن أن تكون المقاييس ذاتية- التسجيل self-reported وتدعى أيضًا مقاييس "دفع-Push"، إذ تسجل كل عملية بناء الوقت الذي تستغرقه، أو أن نحضر البيانات من واجهة برمجية بعد انتهاء العملية وتدعى أحيانًا مقاييس "سحب-Pull". يتمثل خطر التسجيل الذاتي في الوقت الذي ستستغرقه عملية التسجيل بحد ذاتها، والتي قد يكون لها أثر على الوقت الكلي المستغرق للبناء. يمكن أن تُرسل هذه البيانات إلى قاعدة بيانات تعمل وفق سلاسل زمنية time-series DB، أو إلى سِجِل من نوع آخر. هناك عدة خدمات سحابية لتجميع قياساتك بكل سهولة، ومن الخيارات الجيدة الخدمة Datadog. المهام الدورية هناك بعض المهام الدورية التي يجب تنفيذها ضمن فرق تطوير البرمجيات، إذ يمكن أتمتة بعضها من خلال بعض الأدوات المتوفرة، وعليك أتمتة بعضها الآخر. تتضمن الفئة الأولى من المهام الدورية التحقق من الحزم لتفادي الاختراقات الأمنية، وقد تساعدك في ذلك العديد من الأدوات الجاهزة. سيكون بعض هذه الأدوات مجانيًا لمشاريع محددة (مفتوحة المصدر مثلًا) مثل الأداة Dependabot التي يقدمها GitHub. وإليك النصيحة التالية: من الأفضل دائمًا استخدام أدوات جاهزة لأداء هذه المهام، إن سمحت بذلك ميزانيتك، بدلًا من الاعتماد على حلولك الخاصة، فإن لم تكن مهتمًا بتطوير أدوات تتعلق بأمور الأمن مثلًا، استخدم Dependabot للتحقق من الثغرات الأمنية بدلًا من تطوير الأداة بنفسك. لكن ماذا عن المهام التي لا تتوفر لها أدوات مساعدة؟ يمكنك أتمتة هذه المهام بنفسك عن طريق GitHub Actions أيضًا، إذ يزودك GitHub Actions بمُطلِقات أحداث المجدولة scheduled trigger التي يمكن استخدامها لتنفيذ مهمة محددة في وقت محدد. التمارين 11.19 -11.21 11.19: التحقق الدوري من سلامة البرمجيات لدينا الثقة الآن بأنّ خط الإنتاج الذي عملنا عليه سيمنع نشر الشيفرة المخفقة، لكن مع ذلك هناك مصادر عديدة للأخطاء؛ فعندما يعتمد تطبيقنا مثلًا على قاعدة بيانات قد لا تكون متوفرة دائمًا، سيتوقف التطبيق عن العمل في لحظةٍ ما. لهذا من المفيد جدًا التحقق دوريًا من سلامة عمل التطبيق عن طريق إرسال طلب HTTP-GET إلى الخادم. ندعو هذه العملية عادة بعملية التحقق من الاتصال "ping". من الممكن أن نجدول أفعال GitHub لتُحدّث دوريًا وبصورة منتظمة. استخدم الفعل url-health-check أو أي بديل له وجدول عملية التحقق من الخادم الذي تنشر عليه التطبيق. حاول محاكاة الحالة التي يخفق فيها تطبيقك، تأكد حينها أن عملية التحقق ستكتشف الخطأ. اكتب مخطط العمل الدوري الذي أوجدته على ملف خاص. تنبيه: سيستغرق GitHub Actions وقتًا طويلًا حتى يبدأ بتنفيذ مخطط العمل الذي جدولته للمرة الأولى، فقد تطلب منا الأمر قرابة الساعة، لذلك تُعد فكرة إطلاق مخطط العمل مباشرةً بتنفيذ عملية دفع للشيفرة إلى الاستضافة فكرةً جيدة. انتقل بعد ذلك لتنفيذ المخطط المجدول بعد أن تنجح معك هذه الحيلة. تنبيه: عندما تنجح في تنفيذ ما طلبناه، من الأفضل أن تقلل مرات التحقق من الاتصال مع الخادم إلى مرة كل 24 ساعة أو عطل القاعدة، وإلا ستكلفك عملية التحقق المستمرة ساعاتك المجانية المتاحة خلال الشهر. 11.20: خط إنتاج خاص بك ابنِ خط إنتاج CI/CD لبعض التطبيقات التي أنجزتها سابقًا. من التطبيقات المرشحة للعمل عليها تطبيق دليل الهاتف الذي طورناه في القسمين 2 و3 من المنهاج، أو تطبيق المدونة الذي طورناه في القسم 4 والقسم 5، أو تطبيق الطرائف الذي بنيناه بالاستعانة بالمكتبة Redux في القسم 6. ستضطر غالبًا إلى إعادة هيكلية التطبيق لتجمع قطع الشيفرة المتفرقة، وعليك في الخطوة الأولى وضع الواجهتين الأمامية والخلفية في مستودع واحد. لست مجبرًا على ذلك طبعًا، لكنه سيسهل عليك الأمر كثيرًا. إحدى الهيكليات المقترحة هي وضع الواجهة الخلفية في جذر المستودع وأن تضع الواجهة الخلفية ضمن مجلد فرعي، ويمكنك أيضًا نسخ ولصق بنية التطبيق النموذجي الذي نفذناه في هذا القسم، أو أن تحاول الاستفادة من التطبيق النموذجي الذي اطلعنا عليه في القسم 7. ربما من الأفضل أن تنشئ مستودعًا جديدًا لهذا التمرين، ومن ثم تنسخ وتلصق الشيفرة ضمنه. قد تضطر غالبًا في العمل الواقعي إلى تنفيذ ذلك ضمن المستودع القديم، لكن الإنطلاقة الجديدة الآن ستسهل علينا الأمر. سيستغرق منك هذا التمرين وقتًا وجهدًا، لكن الحالة التي تواجهها هنا، وهي بناء خط إنتاج لنشر شيفرة قديمة، شائعة جدًا في الحياة العملية. لن يُنفّذ هذا التمرين في نفس المستودع الذي نفذت فيه التمارين السابقة، لأنك لا تستطيع أن تعيد سوى مستودع واحد إلى منظومة تسليم التمارين، ضع رابطًا إذًا للمستودع الآخر ضمن المستودع الذي أشرت إليه في نموذج التسليم. 11.21: حماية الفرع الرئيسي وتقديم طلب سحب احمِ الفرع الرئيسي للمستودع الذي أنجزت فيه التمرين السابق، وامنع المدراء أيضًا هذه المرة من دمج الشيفرة مع الفرع الرئيسي دون مراجعتها. قدم طلب سحب، واطلب من أحد مستخدمي GitHub التالية أسماؤهم mluukkai و/ أو kaltsoon أن يراجع شيفرتك، وبعد أن تنتهي المراجعة، ادمج الشيفرة مع الفرع الرئيسي، وانتبه إلى أن يكون المراجع من المتعاونين معك في المستودع. اتصل بنا على Discord لكي نراجع شيفرتك، ومن الأفضل إرسال رسالة خاصة تتضمن رابط دعوة. بعدها يكون العمل قد أُنجز. ترجمة -وبتصرف- للفصل Expanding further من سلسلة Deep Dive Into Modern Web Development اقرأ أيضًا المقال التالي: مدخل إلى الحاويات المقال السابق: نشر إصدارات التطبيق بأمان في منظومة التكامل والتسليم المستمر نشر التطبيقات وتوزيعها وفق نهج التسليم المستمر إعداد التكامل المستمر والنشر المستمر باستخدام الخدمتين CircleCI وCoveralls
-
من الجيد الاطلاع على التخطيطات layouts الأكثر استخدامًا لصفحات الويب قبل البدء بتصميمها، وهناك سبب يدفعنا في الواقع للخوض في تصميم الصفحات، إذ ستبدأ العمل عادةً انطلاقًا من صفحة فارغة، ومن ثم يأخذك العمل إلى نواحٍ عدة، فإذا لم تمتلك بعض الخبرة، فستشعر بالقلق عندما تبدأ من نقطة الصفر، ولهذا السبب سنرشدك في هذا المقال إلى قواعد عامة وجوهرية تساعدك في تصميم موقعك بناءً على خبرة طويلة تمتد 25 عامًا. حتى وإن كان التركيز حاليًا على تصميم المواقع المخصصة للهواتف الذكية، لكن المكوّنات الأساسية لبناء صفحات الويب بقيت كما يلي: الترويسة Header: وهي الجزء الذي يظهر أعلى الصفحة ويحتوي على معلومات مكررة في كل الصفحات مثل اسم الموقع وشعاره بالإضافة إلى منظومة سهلة الاستخدام لأغراض التنقل بين الصفحات. المحتوى الرئيسي Main Content: وهي المنطقة الأوسع من الصفحة، وتحتوي على المعلومات الخاصة التي ينبغي عرضها في هذه الصفحة تحديدًا. إضافات ولوحات على الجوانب Stuff on the side: وتضم أيّ شيء لا يجب أن يتواجد في القسم الرئيسي، أي ما يلي: معلومات مشتركة بين مجموعة فرعية من الصفحات. معلومات مكملة لما ورد في المحتوى الرئيسي. منظومة تنقل بديلة. التذييل Footer: يُشاهَد في أسفل الصفحة ويتضمن كما الترويسة معلومات عامة تتعلق بالموقع لكنها أقل أهمية. تشترك الكثير من الصفحات بهذه الأقسام، لكن قد تختلف بطريقة توضعها، وإليك بعض الأمثلة، إذ يمثل 1 الترويسة، ويمثل 2 التذييل، في حين يمثل A المحتوى الرئيسي؛ أما B1 و B2 فهما بعض الأقسام على جانبي الصفحة: تخطيط أحادي العمود: وهو تخطيط مفيد جدًا لمتصفحات الهواتف الجوّالة لتجنب الفوضى في الشاشات الصغيرة. تخطيط ثنائي الأعمدة: ويستهدف عادةً الأجهزة اللوحية لأن شاشاتها أكثر عرضًا من الهواتف الجوالة. تخطيط ثلاثي الأعمدة: ويناسب متصفحات الحواسب المكتبية التي تتميز بشاشات كبيرة على الرغم من أنّ عرض المحتوى ضمن شاشات أصغر هو ما يفضله العديد من مستخدمي الحواسب المكتبية. لكن المتعة الحقيقية ستبدأ عندما تمزج بين التخطيطات الثلاث السابقة في الصفحة نفسها، ويبقى ما عرضناه مجرد أمثلة قد تأخذ بها أو لا. قد تلاحظ كيف يمكن أن يتغير موقع المحتوى الرئيسي في الصفحة إلا أنّ الترويسة (1) تبقى في الأعلى، كما يبقى التذييل (2) في الأسفل، وطالما أنّ المحتوى الرئيسي (A) هو الأكثر أهميةً، فامنحه المساحة الأكبر من الصفحة. إذًا سنعرف في مقالنا على أقسام صفحة الويب والمكان الأفضل لوضعها، وننصحك قبل إكمال قراءة المقال أن تعرف تمامًا ما تريد إنجازه عندما تفكر في تصميم موقع ويب، وسنناقش في مقالات أخرى التصميم المتجاوب للمواقع أي المواقع التي تتغير تخطيطات صفحاتها بناءً على حجم الشاشة. تخطيط أحادي العمود يقدم التخطيط وحيد العمود جميع محتويات الصفحة تقديمًا متتابعًا ومباشرًا، وتذكَّر أنّ الكثير من متابعيك يستعرضون موقعك من خلال الحواسب المكتبية، فاحرص أن يكون المحتوى مقروءًا وسهل الاستعمال على تلك الأجهزة أيضًا. تخطيط ثنائي الأعمدة تُصمَّم المدونات عادةً وفق تخطيط العمودين، إذ يُستخدَم العمود العريض لنشر المحتوى الرئيسي والآخر الضيق لعرض بقية الأشياء مثل بعض المكوّنات الخاصة وأدوات التنقل الإضافية والروابط الإعلانية. انظر إلى الصورة (B1) في الشكل السابق تحت الترويسة مباشرةً، إذ تتعلق هذه الصورة بالمحتوى الرئيسي، لكن المحتوى يبدو معقولًا أكثر دونها، لذلك بالإمكان أن تعدها جزءًا من المحتوى الرئيسي أو من المحتوى الجانبي، وليس الأمر بهذه الأهمية، لأن ما يهم فعلًا هو وضع المحتوى الرئيسي فقط أو ما يتعلق به مباشرةً تحت الترويسة. حالة قد تخدعك إليك هذه الصفحة من موقع MICA التي تبدو وكأنها تستخدِم ثلاثة أعمدة لكنها ليست كذلك: تعوم Float اللوحتين B1 و B2 حول المحتوى الرئيسي، وتذكر المصطلح "يعوم" عندما تبدأ بتعلم التنسيقات المورثة CSS. لِمَ قد نظن أنّ الصفحة منسقة في ثلاثة أعمدة؟ لأن الصورة في أعلى يمين الصفحة لها شكل الحرف "L" ولأن القسم B1 يبدو وكأنه عمود يدعم المحتوى الرئيسي المنزاح، ولأن حرفي "M" و"I" للشعار "MICA" يُشكِّلان خطان عموديان يعطيان انطباعًا قويًا بوجود ثلاث أعمدة، وهذا مثال جيد عن تخطيط كلاسيكي لصفحة ويب مع لمسة إبداعية، فالتخطيط البسيط أسهل تنفيذًا، لكن امنح نفسك مع ذلك فرصةً للاستكشاف والتعبير عن إبداعاتك في هذا المجال. حالة أخرى ستخدعك أكثر تعتمد هذه الصفحة من موقع The Opera de Paris على تخطيط العمودين، لكنك ستلاحظ العديد من الحيل هنا وهناك قد تشوش نظرتك إلى تخطيطها، فالترويسة تحديدًا تتداخل مع صورة المحتوى الرئيسي، وطريقة انحناء قائمة الترويسة التي تتماشى مع الانحناء أسفل الصورة تجعلنا نتوقع أنهما شيء واحد علمًا أنهما تقنيًا مختلفان تمامًا، كما تبدو الصورة السابقة المأخوذة لموقع "Opera" أكثر تعقيدًا من الصورة التي تسبقها من موقع "MICA"، لكنها أسهل تنفيذًا مع الانتباه إلى نسبية الكلمة "سهل". وهكذا نرى إمكانية إبداع مواقع ويب رائعة بتخطيطات بسيطة، وألق نظرةً إذًا على مواقع الويب التي تفضِّلها ثم اسأل نفسك أين الترويسة؟ أين المحتوى الرئيسي والجانبي والتذييل؟ سيلهمك ذلك إلى تصاميم خاصة بك ويمنحك تلميحات عما يفيدك في عملك وعما لا يفيد. ترجمة -وبتصرف- للمقال ?What do common web layouts contain. اقرأ أيضًا المقال السابق: البدء بتصميم موقع ويب التحكم في تخطيط الصفحة وضبط محاذاة العناصر في CSS
-
يغطي هذا المقال الخطوة الأولى والأهم للانطلاق في أيّ مشروع، وهي تحديد ما نريده من مشروعنا وخصوصًا مواقع الويب، إذ يركِّز الكثيرون في هذا المضمار على الجانب التقني من المشروع، لكن ما يهم فعلًا -وعلى الرغم من أهمية التقنية التي يستخدِمها المرء في حرفته- هي الغاية التي ينشد الوصول إليها، فالكثير من المشاريع التي أخفقت لم يكن سبب إخفاقها هو الناحية التقنية أو المعرفية، وإنما ضبابية أهدافها ورؤيتها، لهذا السبب، عندما تخطر في بالك فكرةً وتريد نقلها لتصبح موقع ويب، لا بد لك من الإجابة على بعض الأسئلة قبل أيّ شيء آخر: ما الذي أريد إنجازه بدقة؟ كيف سيساعدني موقع الويب في الوصول إلى أهدافي؟ ما الذي يتوجب علي فعله وبأي ترتيب للوصول إلى أهدافي؟ تُدعى هذه الخطوات فكرة المشروع أو التصور الأولي للمشروع project ideation، وهي ضرورية للوصول إلى هدفك سواءً كنت مبتدئًا أم مطوّرًا محترفًا. لا يبدأ المشروع عادةً بالالتفات إلى نواحيه التقنية، فلا يؤلف الموسيقيون مقطوعاتهم حتى يتكون لديهم تصوّر أولي لما يرغبون في عزفه، ولا الرسامون ولا الكتَّاب ولا مطورو مواقع الويب، إذ تأتي التقنية ثانيًا، كما لا ينفي ذلك اطلاقًا الدور الحيوي للتقنية، فلا بد أن يتقن الموسيقيون العزف على الآلات، لكنهم لا يقدِّمون أعمالًا دون تصوّر لما سيقدِّمونه، لهذا عليك التروِّي والعودة إلى التفاصيل لتقرِّر ما تريده قبل القفز إلى كتابة الشيفرة واستخدام أدوات البناء. سيساعدك الجلوس ومناقشة أفكارك مع أصدقائك، لكن لا تتوقع فائدةً كبيرةً، إذ عليك الجلوس وتنظيم أفكارك لتصل إلى رؤية واضحة للطريق الذي ستمشيه لتحويل أفكارك إلى واقع، فجُلّ ما تحتاجه في هذه المرحلة قلم وورقة وبعض الوقت للإجابة على الأسئلة التي سنطرحها تباعًا في مقالنا. ما الذي أريد إنجازه بالتحديد؟ يبدو أنّ هذا السؤال هو الأهم لأنه يقود كل شيء آخر، لذا ضع قائمةً بكل الأهداف التي تريد تحقيقها مثل بيع البضائع لكسب المال أو التعبير عن آراء سياسية أو التعرف على أصدقاء جدد، أو أيّ شيء تريده. افترض أنك موسيقي وقد ترغب بأن: يستمع الناس إلى موسيقاك. تبيع بعض المنتجات. تتعرف على موسيقيين آخرين. تناقش الآخرين بموسيقاك. تعلم الموسيقى من خلال الفيديوهات. تنشر صورًا لقططك. تتعرف على أصدقاء جدد. عندما تنتهي من وضع قائمة الأهداف، فلا بدّ من ترتيبها حسب الأولوية التي تراها من الأكثر إلى الأقل أهمية والتي قد تكون بالصورة التالية: التعرف على أصدقاء جدد. استماع الناس إلى موسيقاك. مناقشة الآخرين بموسيقاك. التعرف على موسيقيين جدد. بيع بعض المنتجات. تعليم الموسيقى من خلال الفيديوهات. نشر صور لقططك. سيساعدك التمرّن على كتابة أهدافك بهذه الصورة على اتخاذ القرارات (هل عليّ تنفيذ هذه الميزات أو استخدام هذه الخدمات أو اعتماد تصاميم معينة)، وبعد ترتيبنا لقائمة الأهداف، فلننتقل إلى السؤال الثاني. كيف سيقربني موقع الويب من أهدافي؟ وضعتَ قائمةً بأهداف وترى أنك بحاجة إلى موقع ويب لتحقيق هذه القائمة، ولنعد قليلًا إلى عناصر القائمة، سنجد أنها تضم خمسة أهداف تتعلق بالموسيقى، وهدف يتعلق بالعلاقات الشخصية، وأخيرًا هدف ليس له علاقة إطلاقًا بالموسيقى وإنما بصور القطط، فهل من المنطقي بناء موقع ويب يحقق كل هذه الأهداف؟ هل الأمر ضروري؟ فقد تجد أن خدمات الويب الموجودة قد تحقق أهدافك دون عناء بناء موقع ويب جديد، فالتعرف على أصدقاء جدد مثلًا هي حالة واضحة للاستفادة من تلك الخدمات، إذ ستمُضي وقتك في تصميم وبناء وصيانة موقع بدلًا من البحث جديًا على أصدقاء جدد. طالما أنّ أهم ما في الأمر هو الوصول إلى أهدافنا، فمن الأفضل استغلال إمكانياتنا في تجريب الأدوات الموجودة بدلًا من البدء من الصفر، وكذلك الأمر بالنسبة إلى نشر الصور، إذ توجد فعلًا خدمات كثيرة لهذه الغاية، ولا مبرر أبدًا لإهدار الوقت في بناء موقع ويب لنشر صور القطط، كما ترتبط الأهداف الخمسة الأخرى بالموسيقى، وستجد الكثير من خدمات الويب التي تغطي هذه الأهداف، لكن من المنطقي في هذه الحالة التفكير في بناء موقع ويب خاص بك لهذه الغايات، فقد يساعدك موقع الويب في تجميع كل الأشياء التي تحتاجها في مكان واحد (وهذا أمر مفيد في تحقيق الأهداف 3 و5 و6) ويعزز العلاقات بينك وبين العامة (تكمن فائدته في تحقيق الهدفين 2 و4). باختصار، وطالما أن الأهداف تحوم حول الموضوع نفسه، فقد يساعدنا تجميع كل شيء في المكان نفسه على تحقيق أهدافنا، كما يساعد متابعينا في التواصل معنا، وبالتالي ستجد الطريق الأفضل لبلوغ أهدافك دون أن تبدد جهودك سدًى عند الإجابة على السؤال "كيف يساعدني موقع الويب في الوصول إلى أهدافي؟". ما الذي يتوجب علي فعله وبأي ترتيب للوصول إلى أهدافي؟ الآن وقد حددت أهدافك، فقد حان الوقت لتحويل هذه الأهداف إلى خطوات قابلة للإنجاز، وعليك التذكُّر دائمًا بأنّ الأهداف تتطور مع الوقت حتى عند تنفيذ المشروع وليست جامدةً، وخاصةً عندما تصادف عقبات غير متوقعة أو عندما ستغير رأيك بمسألة ما. لنعد إلى مثالنا السابق بدلًا من الإسهاب في التفسيرات ولنوضح الأمر: ليستمع الناس إلى موسيقاك عليك ما يلي: تسجيل بعض الألحان. تحضير بعض الملفات الصوتية التي يمكن استخدامها على الويب (هل يمكن الاستفادة من خدمة موجودة؟). امنح الآخرين إمكانية الوصول إلى موسيقاك في بعض أقسام موقعك. لمناقشة الآخرين بموسيقاك عليك ما يلي: كتابة بعض المقالات لبدء الحوار. حدِّد الطريقة التي ستظهر عليها مقالاتك. انشر هذه المقالات على الويب. للتعرف على موسيقيين جدد عليك ما يلي: زوّد متابعيك بقنوات للتواصل معك (بريد إلكتروني، فيس بوك، هاتف، بريد). حدد الطريقة التي سيصل فيها الآخرون إلى قنوات الاتصال التي توفرها عبر موقعك. لبيع بعض المنتجات عليك ما يلي: حضِّر منتجاتك وخزّنها. جِد طريقةً مناسبةً لشحنها. جِد طريقةً مناسبةً للدفع. جِد آليةً مناسبةً على موقعك تسهِّل على الناس طلب منتجاتك. لتعليم الموسيقى من خلال الفيديوهات عليك ما يلي: سجِّل مقاطع فيديو لدروسك. اجعل فيديوهاتك مناسبةً للاستعراض عبر الويب (مجددًا، هل يمكن الاستفادة من خدمة موجودة؟). امنح الآخرين إمكانية الوصول إلى فيديوهاتك في بعض أقسام موقعك. تجدر الإشارة هنا إلى نقطتين: الأولى: وهي أنّ بعض الأعمال لا تتعلق بالويب مثل تسجيل الموسيقى وكتابة المقالات، ولهذه النشاطات التي تجري دون اتصال بالإنترنت أهمية كبيرة قد تفوق الجانب المرتبط بالويب في مشروعك، فعندما تهتم ببيع منتجات على سبيل المثال، فمن الأجدى والأوفر من ناحية الوقت إيجاد حلول لتأمين المنتجات وطريقة للدفع والشحن قبل الشروع في بناء الموقع الذي سيستخدِمه الآخرون في طلب تلك المنتجات. الثانية: تحضير خطوات قابلة للتنفيذ سيقودك غالبًا إلى أسئلة جديدة عليك البحث عن إجابة لها. إذ ستجد عادةً مزيدًا من الأسئلة أكثر مما قد تتوقع مثل هل عليَّ تعلّم كل هذه الأمور بنفسي؟ هل أطلب من شخص آخر ذلك؟ هل استخدم خدمات تؤمنها أطراف أخرى؟ الخلاصة كما رأينا، قد تقودك فكرة بسيطة مثل "أريد بناء موقع ويب" إلى قائمة طويلة من الخطوات التي ينبغي تنفيذها والتي تنمو أكثر كلما فكرت بتفاصيلها أكثر، وقد يطغى الأمر على تفكيرك بسرعة، فلا حاجة للإجابة على كل الأسئلة، ولن تضطر إلى تنفيذ كل ما وضعته على قائمتك، فالأهم هنا أن يكون لديك تصوّر عما تريد وكيف ستصل إلى مبتغاك، وحالما تتوضَّح الرؤية، عليك أن تقرِّر متى وكيف تبدأ، وجزِّء المهام الضخمة إلى خطوات أصغر قابلة للتنفيذ بحيث تصل بك في النهاية إلى الإنجاز الذي تنتظر. نأمل أن ترشدك هذه المقالة إلى رسم ملامح خطتك لبناء موقع ويب، وربما سيكون مناسبًا الاطلاع على الطريقة التي تعمل بها شبكة الإنترنت على أساس خطوة ثانية. ترجمة -وبتصرف- للمقال ?How do I start to design my website. اقرأ أيضًا الفرق بين مصمم الويب ومطور الويب وكيفية معرفة الأنسب بينهما أدوات ضرورية لتصميم مواقع الويب HTML و CSS للمبتدئين: كيف تصمم أول صفحة ويب لك 50 تصميمًا مميزًا لمواقع إلكترونية نموذجية يحتذى بها
-
تُعد أداة التهيئة في راسبيري باي حزمةً برمجيةً فعالةً لضبط كثيرٍ من الإعدادات على جهاز راسبيري باي، ابتداءً من الواجهات المتوفرة في الجهاز وصولًا إلى البرامج والتحكُّم بها عبر الشبكات الحاسوبية. قد يصعُب ضبط الإعدادات المختلفة على المستخدمين الجدد، لذلك سيأخذ هذا الملحق بيدك خطوةً خطوة في كل شرح كل إعداد وبيان الغاية منه. تستطيع تحميل الأداة من قائمة راسبيري باي ضمن فئة "التفضيلات Preferences"، أو من خلال واجهة سطر الأوامر بكتابة الأمر التالي في نافذة برنامج "الطرفية Terminal": raspi-config ستجد اختلافًا بين طريقتي عرض النسخة الرسومية لأداة التهيئة ونسخة واجهة سطر الأوامر، إذ ستظهر الخيارات في فئات مختلفة. سيعتمد هذا الملحق على النسخة الرسومية. نافذة النظام تضم نافذة النظام System tab خيارات تتحكم بمجموعة الإعدادات التالية: كلمة المرور Password: انقر على الزر "تغيير كلمة المرور Change Password" لاختيار كلمة مرور جديدة للمستخدم الحالي (المستخدم 'pi' هو المستخدم الافتراضي). اسم المضيف Hostname: وهو الاسم الذي يعرِّف به باي نفسه على الشبكات، إذ ينبغي أن يمتلك كل جهاز باي اسمًا فريدًا إن كان هناك عدة أجهزة على نفس الشبكة. واجهة الإقلاع Boot: سيقلع باي وصولًا إلى "سطح المكتب Desktop" بالوضع الافتراضي للإعداد، ويمكن اختيار "To CLI" للإقلاع وصولًا إلى واجهة سطر الأوامر التي شرحناها في الملحق "C". تسجيل دخول تلقائي Auto Login: عندما يكون الخيار "مثل مستخدم حالي As current user" مفعلًا (وهو مفعلٌ افتراضيًا)، سيحمّل راسبيان سطح المكتب دون طلب اسم المستخدم وكلمة المرور. التحقق من الاتصال بالشبكة عند الإقلاع Network Boot: إذا كان الخيار "انتظار شبكة الاتصال wait for network" مفعلًا، فلن يُحمّل راسبيان سطح المكتب حتى يضمن وجود اتصال بالشبكة. شاشة مؤقتة Splash Screen: عندما يُفعَّل هذا الخيار، تختفي رسائل إقلاع راسبيان خلف شاشة رسومية مؤقتة. فيديو باي 4 Pi 4 Video: يُتاح هذا الإعداد في النموذج Pi 4 ويعطيك القدرة على تبديل مخرج الفيديو، إذ يمكِّنك الخيار "4K HDMI" من بث الفيديوهات بدقة "4K" عبر أحد منفذي micro أو HDMI أو كلاهما؛ بينما يمكِّن الخيار "تماثلي Analog" عرض الفيديوهات المركبة composite video عبر منفذ الفيديو 3.5 مم، ويُعد هذا الخيار جيدًا إذا كان لديك شاشة أو تلفاز قديم ليس له منفذ HDMI. لا يُفعّل افتراضيًا أيًا من الخيارين السابقين وتُعرض الفيديوهات بدقة 1080p عبر منافذ micro أو HDMI. انتبه إلى أنّ تفعيل الخيار "4K" سيزيد من استهلاك الطاقة والحمل على وحدة المعالجة المركزية CPU ووحدة معالجة الرسوميات GPU، لذلك من الأفضل إلغاء تفعيل هذا الخيار إذا لم تكن بحاجته حاجةً ماسةً لتوجيه موارد الجهاز لمهامٍ أخرى. نافذة الواجهات وتضم الإعدادات التي تتحكم بواجهات العتاد الصلب المتوفرة على باي، وهي: الكاميرا Camera: يمكّن أو يعطّل واجهة الكاميرا التسلسلية Camera Serial Interface -أو اختصارًا CSI-، للتعامل مع تجهيزة كاميرا راسبيري باي. SSH: يمكّن أو يعطّل واجهة المفسر المؤمّنة Secure Shell Interface، والتي تسمح بتشغيل واجهة سطر الأوامر على باي من حاسوب آخر على الشبكة باستخدام عميل SSH. VCN: يمكّن أو يعطّل واجهة الشبكة الافتراضية Virtual Network Computing، والتي تسمح لك باستعراض الواجهة الرسومية لسطح مكتب باي من حاسوب آخر على الشبكة باستخدام عميل VCN. SPI: يمكّن أو يعطّل واجهة الطرفيات التسلسلية Serial Peripheral Interface، التي تُستخدم للتحكم ببعض التجهيزات المتصلة بالمنصة GPIO. I2C: يمكّن أو يعطّل الممر الناقل بين الدارات المتكاملة Inter-Integrated Circuit التي تُستخدم للتحكم ببعض التجهيزات المتصلة بمنصة GPIO. المنفذ التسلسلي Serial Port: يمكّن أو يعطّل المنفذ التسلسلي Serial port الخاص براسبيري باي والمُتاح عبر المنصة GPIO. واجهة سطر الأوامر التسلسلية Serial Console: تمكّن أو تعطّل واجهة الأوامر التسلسلية المتاحة للمنفذ التسلسلي، ويمكن تعديل هذا الإعداد عند تمكين الإعداد Serial Port. 1-Wire: يمكّن أو يعطّل الواجهة 1-Wire التي تُستخدم للتحكم ببعض التجهيزات المتصلة بمنصة GPIO. Remote GPIO: تمكّن أو تعطّل خدمة شبكة تسمح بالتحكم بمنصة GPIO لحاسوب باي من حاسوب آخر على الشبكة باستخدام المكتبة GPIO Zero. نافذة الأداء وتضم الإعدادات التي تتحكم بحجم الذاكرة المتاحة وسرعة عمل المعالج. رفع تردد التشغيل Overclock: يتيح لك هذا الإعداد جملةً من الخيارات التي تزيد أداء باي لكنه بالمقابل يزيد من استهلاك الطاقة والحرارة واحتمال قصر عمر التجهيزة؛ وهو غير متاح في كل نماذج باي. ذاكرة وحدة المعالجة الرسومية GPU Memory: وتتيح لك ضبط حجم الذاكرة المخصص للاستخدام من قبل معالج رسوميات باي. قد تزيد الذاكرة التي تزيد عن 128 ميغا بايت (افتراضية) الأداء أثناء تصيير الرسوميات ثلاثية الأبعاد والمهام الإعتيادية لوحدة معالجة الرسوميات للأغراض العامة general-purpose GPU -أو اختصارًا GPGPU-، على حساب الذاكرة المخصصة لنظام التشغيل راسبيان؛ بينما يحسِّن تخفيض الذاكرة المخصصة للرسوميات أداء بعض المهام الحساسة للذاكرة على حساب انخفاض أداء تصيير الرسوميات ثلاثية الأبعاد والكاميرا وبعض ميزات عرض الفيديوهات التي قد تصبح غير متاحة. نافذة إعدادات الموقع الجغرافي وتضم الإعدادات التي تتحكم بالمنطقة الجغرافية التي صّممت باي لتعمل ضمنها بما في ذلك إعدادات لوحة المفاتيح. محلي Locale: يسمح لك باختيار موقعك، وهو إعدادٌ يتعلق بالنظام نفسه ويضبط اللغة والبلد ومجموعات المحارف. انتبه إلى أنّ تغيير اللغة في هذا الإعداد سيؤثر فقط على لغة التطبيقات التي تتوفر ترجمةً لها إلى اللغة المختارة. المنطقة الزمنية TimeZone: ويتيح لك اختيار منطقتك الزمنية وذلك بانتقاء منطقة من العالم يليها اختيار أقرب مدينة إليك. إذا اتصلت باي بالانترنت وعرضت الساعة توقيتًا خاطئًا، يكون السبب عادةً اختيار منطقة زمنية خاطئة. لوحة المفاتيح Keyboard: يتيح لك اختيار نمط لوحة المفاتيح ولغتها ومخطط محارفها؛ فإذا لاحظت أن لوحة المفاتيح تطبع حروفًا أو رموزًا خاطئةً، يمكن تصحيحها من خلال هذا الإعداد. البلد الذي تستخدم فيه WIFI: ويسمح لك باختيار البلد لأغراض تنظيم استخدام أمواج الراديو للاتصال اللاسلكي. احرص على اختيار البلد الذي تستخدم فيه باي، فاختيارك لبلد آخر قد يُفقدك القدرة على الاتصال بنقاط الوصول اللاسلكية المجاورة التي قد تخضع لقوانين البث اللاسلكي. إذًا، من الأفضل اختيار البلد قبل محاولة الاتصال بالشبكات اللاسلكية. ترجمة -وبتصرف- للملحق The Raspberry Pi Configuration Tool من كتاب The Official Raspberry Pi Beginner's Guide اقرأ أيضًا المقال السابق: واجهة سطر أوامر راسبيان في راسبيري باي تجميع راسبيري باي والتحضير لاستعماله إعداد Raspberry Pi للعمل
-
تستطيع الوصول إلى معظم برامج راسبيري باي عبر سطح المكتب، إلا أنك تحتاج واجهةً لكتابة تعليمات نصية تُعرف بواجهة سطر الأوامر Command-line interface -أواختصارًا CLI- للوصول إلى بعض البرامج. يؤمن هذه الواجهة في راسبيان تطبيقٌ يُدعى "الطرفية Terminal". لن يحتاج معظم المستخدمين إلى تعلُّم العمل عبر واجهة سطر الأوامر CLI، لكن ما سيقدمه هذا الملحق هو مدخلٌ بسيط لمن يرغب بتعلم مزيدٍ عنها. فتح تطبيق الطرفية يصل المستخدم إلى CLI عبر برنامجٍ يُدعى "الطرفية Terminal"، وهو برنامج يُحمِّل ما يُعرف تقنيًا بواجة الطباعة الافتراضية عن بُعد Virtual teletype terminal؛ إذ تعود هذه التسمية إلى الفترة الزمنية التي أعطى فيها مستخدمي الحاسوب الأوامر عبر آلة كاتبة كهروميكانيكية بدلًا من استخدام لوحة المفاتيح والشاشة. يمكنك فتح الطرفية عن طريق النقر على أيقونة راسبيري لفتح القائمة والانتقال إلى فئة "برامج ملحقة Accessories"، ثم النقر على "الطرفية Terminal". يمكن سحب نافذة الطرفية إلى سطح المكتب كما يمكن تكبيرها وتصغيرها وتغيير حجم خط الكتابة إن كان من الصعب قراءته، أو ليناسب حجم النافذة وذلك بالنقر على القائمة "تحرير Edit" ثم اختيار "تكبير Zoom in"، أو "تصغير Zoom out"K أو بالضغط على المفتاح "CTRL" ثم أحد الزرين "+" أو "-". محث الطرفية أول ما تراه في الطرفية هو المحث Prompt الذي يكون منتظرًا تعليماتك. يظهر المحث في راسبيان على الشكل التالي: pi@raspberrypi:~ $ يشير الاسم ما قبل "@" إلى اسم المستخدم وما بعده إلى اسم الحاسوب الذي تستخدمه وهو افتراضيًا "raspberrypi". بعد الرمز ":" ستشاهد الرمز "~" وهو اختصارٌ يشير إلى المجلد الرئيسي Home directory ويمثِّل مجلد العمل الذي تعمل ضمنه حاليًا current working directory -أواختصارًا CWD-؛ أما الرمز "$" فيشير إلى أن المستخدم الحالي غير مفوّض unprivileged، أي يحتاج إلى كلمة مرور ليُنفّذ مهامًا، مثل إضافة أو إزالة البرامج. الانطلاق في العمل اكتب التعليمة التالية ثم اضغط المفتاح "Enter": cd Desktop سيتغير المُحِث إلى: pi@raspberrypi:~/Desktop $ أصبح سطح المكتب الآن هو مجلد العمل الحالي الذي يقع مباشرةً تحت المجلد الرئيسي، والذي يشير إليه الرمز "~"، ونُفِّذ ذلك من خلال تعليمة تغيير مجلد العمل cd. يمكنك العودة إلى المجلد الرئيسي بأربعة طرق، حاول أن تجرب كل منها على حدى، ثم جرّب استخدامها للعودة إلى مجلد فرعي لسطح المكتب. الطريقة الأولى- باستخدام الأمر التالي: cd .. إذ يُعد الرمز ".." اختصارًا للمجلد الذي يقع مباشرةً فوق مجلد العمل الحالي أو المجلد الأب، وطالما أنّ المجلد الرئيسي هو الأب المباشر لمجلد سطح المكتب فستصل إليه. عُد إلى سطح المكتب وحاول تجريب الأمر التالي. الطريقة الثانية- باستخدام الأمر التالي: cd ~ ويعني الأمر حرفيًا "توجَّه إلى المجلد الرئيسي"، إذ يمكنك الانتقال بهذه التعليمة إلى المجلد الرئيسي من أي مجلد تعمل عليه، على خلاف الطريقة الأولى التي تنقلك إلى المجلد الأب الأعلى مباشرةً من مجلد العمل الحالي. عُد إلى سطح المكتب وحاول تجريب الطريقة الثالثة التالية. الطريقة الثالثة- باستخدام الأمر التالي: cd إذا لم تضع عنوان المجلد الذي ستنتقل إليه بعد التعليمة cd سيقودك افتراضيًا إلى المجلد الرئيسي. عُد إلى سطح المكتب وحاول تجريب الأمر الأخير التالي. الطريقة الرابعة- باستخدام الأمر التالي: cd /home/pi إذ يمثِّل المسار ما بعد التعليمة cd المسار المطلق absolute path والذي سيعمل بغض النظر عن المجلد الحالي، وينقلك إلى المجلد الرئيسي من أي مجلد تعمل عليه كما هو حال التعليمتين السابقتين، لكن عليك ذكر اسم المستخدم (pi في حالتنا هذه). التعامل مع الملفات لكي تتمرن على أساليب التعامل مع الملفات، انتقل إلى سطح المكتب واكتب الأمر: touch Test سيظهر على سطح المكتب عند تنفيذ التعليمة السابقة ملفٌ اسمه "Test"، إذ تُستخدم التعليمة touch عادةً لتحديث معلومات الوقت والتاريخ لملف، لكن في الحالة التي لا يكون فيها هذا الملف موجودًا (مثل حالتنا) تُنشئ التعليمة هذا الملف. جرّب التعليمة التالية: cp Test Test2 سيظهر على سطح المكتب ملفٌ آخر باسم "Test2" ويمثّل نسخةً مطابقةً للملف الأصلي. لنحذف هذه النسخة على النحو التالي: rm Test2 لن يظهر الملف على سطح المكتب بعد الآن. حاول أن تجرّب الآن التعليمة التالية: mv Test Test2 تنقل هذه التعليمة الملف "Test"، إذ سيختفي عن سطح المكتب ليحل محله الملف "Test2"، الذي يعد نسخةً مطابقةً أيضًا عن الملف الأصلي، وتُستخدم هذه الطريقة في تغيير اسم ملف مثلًا. إذا لم يكن سطح المكتب هو مجلد العمل الحالي، قد تحتاج إلى معرفة ما يحتويه هذا المجلد من مجلدات وملفات لذلك اكتب التعليمة: ls إذ تًظهر هذه التعليمة قائمةً بمحتويات المجلد الحالي أو محتويات أي مجلد آخر تحدده لهذه التعليمة. أضِف بعض الخيارات إلى تعليمتك لتتمكن من عرض تفاصيل أكثر، مثل الملفات المخفية وحجم الملفات: ls -larth تتحكم الخيارات التالية بتعليمة ls: l: يعرض النتائج في قائمة عمودية طويلة. a: يعرض جميع الملفات والمجلدات. r: يعكس الترتيب الاعتيادي للمعروضات. t: يعرض المحتويات وفقًا لتاريخ أخر تعديل، ومع r سيعرض لك الملفات الأقدم في بداية القائمة. h: يُظهر حجم الملف بطريقة مقروءة للبشر ليسهل فهمه. تشغيل البرامج لا يمكن تشغيل بعض البرامج إلا باستخدام سطر الأوامر، بينما يمتلك البعض الآخر واجهات رسومية وواجهة لسطر الأوامر؛ إذ تُعد "أداة تهيئة البرمجيات Pi software configuration tool" مثالًا عن الحالة الأخيرة، والتي تُشغَّل عادةً من قائمة راسبيري باي. لنجرّب طريقة سطر الأوامر بكتابة التعليمة: raspi-config ستكون نتيجة التعليمة رسالة خطأ مفادها أنه لا يمكن تشغيل البرنامج إلا في حالة كان مستخدم جذر رئيسي root user، لذلك حاول تغيير التعليمة إلى: sudo raspi-config التوجيه sudo هو اختصار لعبارة "switch-user do"، وهي تجبر راسبيان على تنفيذ الأمر كأنه مستخدمٌ رئيسي. لا تستخدم هذا التوجيه ما لم يتطلب البرنامج الذي تشغله امتيازات عالية مثل حالة تثبيت أو إزالة برامج أو ضبط إعدادات النظام، فلا يجب أن تُشغّل لعبة مثلًا باستخدام sudo. اضغط على المفتاح "TAB" مرتين، ثم اختر "إنهاء Finish" واضغط على المفتاح "Enter" لإغلاق أداة التهيئة والعودة إلى واجهة سطر الأوامر. نفذ أخيرًا التعليمة التالية: exit التي ستنهي جلسة العمل وتغلق برنامج الطرفية. استخدام الطرفيات TTYs لا يمثِّل برنامج "الطرفية Terminal" الواجهة الوحيدة لسطر الأوامر، بل بالإمكان الانتقال إلى أية طرفيات قيد العمل، والتي تُعرف بواجهات الأوامر البعيدة teletype -أو اختصارًا TTYs-. للانتقال إلى tty2 اضغط على المفتاحين "CTRL" + "ALT" معًا واضغط معهما الزر "F2". لا بدّ من تسجيل دخولك باستخدام كلمة المرور واسم المستخدم، وستتمكن بعد ذلك من التعامل مع هذه الطرفية كما فعلنا سابقًا. هذه الطرفيات مفيدةٌ خاصةً عندما لا تكون قادرًا على الوصول إلى سطح المكتب لسببٍ أو لآخر. لمغادرة tty2 اضغط على المفتاحين "CTRL" + "ALT" معًا واضغط معهما الزر "F7". عند العودة إلى tty2 مجددًا سترى كل ما أنجزته سابقًا قبل مغادرتها. اكتب التعليمة exit ثم اضغط على المفاتيح "CTRL+ALT+F7" للعودة إلى سطح المكتب، وتأتي أهمية تنفيذ هذه التعليمة قبل مغادرة TTY في تسجيل خروجك تلقائيًا، إذ سيتمكن أي شخصٍ قادرٍ على الوصول إلى TTY من العبث بحسابك دون الحاجة لكتابة كلمة المرور. تهانينا، لقد اجتزت خطوتك الأولى في احتراف واجهة سطر الأوامر الخاصة بالنظام راسبيان. ترجمة -وبتصرف- للملحق The command-line interface من كتاب The Official Raspberry Pi Beginner's Guide اقرأ أيضًا المقال التالي: أداة التهيئة في راسبيري باي المقال السابق: تثبيت أنظمة التشغيل والبرامج على راسبيري باي إنشاء أمر جديد في بيئة سطر الأوامر في راسبيري باي التعامل مع بيئة سطر الأوامر في راسبيري باي
-
لابد من نشر الموقع على شبكة الإنترنت حالما تنتهي من كتابة الشيفرة وتنظيم الملفات التي تكوّنه ليتمكن الجميع من الوصول إليه، إذ سنشرح في هذا المقال كيف تنشر موقعك التجريبي البسيط على الإنترنت بأقل جهد ممكن. ماهي الخيارات المتاحة يُعَدّ نشر موقع ويب موضوعًا معقّدًا لوجود طرق وأساليب كثيرة لتنفيذه، ولن نحاول في هذا المقال توثيق كل الطرق الممكنة، وإنما سنصف إيجابيات وسلبيات ثلاثة نهج مناسبة للمبتدئين، ثم نفصّل إحداها والتي تُعَدّ الأفضل للكثير من القراء. الحصول على استضافة واسم نطاق يفضِّل الكثيرون الدفع مقابل الحصول على استضافة واسم نطاق وذلك لتحكّم أفضل في محتوى ومظهر موقع الويب: الاستضافة Hosting: هي مساحة تخزين مُستأجَرة على خادم ويب تابع لشركة الاستضافة، إذ توضَع ملفات الموقع على هذا الخادم الذي يتيح محتواه للزائرين. اسم النطاق Domain name: هو العنوان الفريد الذي ستجد عليه موقع ويب محدَّد مثل /hsoub أو /google، ويمكنك استئجار اسم النطاق لعام أو أكثر من شركة مُسجّلة Domain Registrar. تستخدِم معظم مواقع ويب الاحترافية الطريقة السابقة لتنشر محتواها على شبكة الإنترنت، وبالإضافة إلى ذلك، سيتطلب الأمر برنامجًا يستخدِم بروتوكول نقل الملفات FTP لنقل ملفاتك إلى الخادم، ويمكنك الاطلاع على مقال أساسيات تحديد الكلفة المادية الكاملة لبناء موقع ويب، كما تتنوع برامج FTP كثيرًا، لكن وظيفتها بالمجمل هي استخدام المعلومات التي تزودك بها شركة الاستضافة وهي اسم المستخدِم وكلمة المرور واسم المضيف عادةً، وذلك لتأمين الاتصال مع خادم الاستضافة ونقل الملفات إليه، ثم يُظهِر البرنامج بعد الاتصال ملفاتك المحلية وملفات خادم الويب في نافذتين متجاورتين ليسهل نقل الملفات بين المكانين. نصائح لإيجاد استضافة ونطاق لا نرشح في هذا المقال أيّ شركة استضافة أو شركة مسجِّلة، فعليك البحث بنفسك عما يناسبك، إذ تتيح لك كل المسجلات وسيلةً للتحقق من توفر اسم نطاق معين وحجزه. تمنحك بعض مزودات الخدمة الموجودة على حاسوبك الشخصي أو ضمن شبكة مكتبك إمكانية استضافة محدودة لموقعك، إذ لن تكون الميزات المتاحة كثيرةً، لكنها ممتازة لتجربته الموقع. ستجد أيضًا خدمات استضافة مجانية مثل Neocities و Google sites و Blogger و Wordpress، وقد تجني فائدة ما تدفع، لكن موارد مجانية مثل هذه قد تكوِّن خيارًا تجريبيًا ممتازًا أيضًا. تزوّدك بعض الشركات بخدمتي الاستضافة وحجز أسماء نطاقات معًا. استخدام أدوات على شبكة الإنترنت مثل جيت-هاب و جوجل آب تساعدك بعض الأدوات في نشر موقعك مثل: جيت-هاب GitHub: وهو موقع كتابة شيفرة تشاركي يسمح لك برفع ملفات الشيفرة إلى مستودعات تخزين على منظومة التحكم بالإصدار Git، إذ تستطيع بعد ذلك مشاركة شيفرة المشاريع المختلفة والتعاون في العمل عليها، وطالما أنّ المنظومة مفتوحة المصدر، فيمكن لأيّ كان الوصول إلى الشيفرة على جيت-هاب واستخدامها والتعلم منها وتطويرها، كما تقدِّم جيت-هاب أيضًا ميزةً مفيدةً هي صفحات جيت-هاب GitHub Pages التي تسمح لك باستضافة شيفرة موقعك على ويب. محرّك جوجل آب Google App Engine: وهي منصة قوية تسمح لك ببناء وتشغيل التطبيقات بالاستفادة من البنية التحتية لجوجل، سواءً أردت بناء تطبيق ويب من الصفر أو استضافة موقع ويب ساكن، ولمزيد من المعلومات راجع مقال رفع موقع ويب إلى شبكة الإنترنت. هناك عدة خيارات أخرى مجانية، لكنك قد تتخطى بسهولة حدود الميزات المتاحة. استخدام بيئة عمل متكاملة مبنية على ويب هناك العديد من تطبيقات الويب التي تحاكي بيئة تطوير مواقع ويب وتسمح لك بإدخال شيفرة HTML و CSS وجافاسكربت واستعراض نتيجة تنفيذ الشيفرة على أساس موقع ويب حقيقي داخل نافذة المتصفح، وتُعَدّ هذه الأدوات عمومًا سهلة الاستخدام نسبيًا وممتازةً لأغراض التعلّم ومشاركة الشيفرة، إذ بإمكانك إذا أردت مشاركة أسلوب برمجي أو طلب مساعدة في تنقيح شيفرة من زميل في مكتب مجاور، كما أنها مجانية لبعض الميزات الأساسية، لكنها لا تزوّدك عادةً بمساحة لتخزين ملفات الدعم أو ملفات المساعدة والتي تدعى بالأصول assets مثل الصور، وحاول أن تجرب بعضها مثل JSFiddle و Glitch و JS Bin و CodePen g لتجد ما يناسبك. النشر باستخدام جيت-هاب سنناقش الآن كيف تنشر موقعك على صفحات جيت-هاب بسهولة: سجّل في موقع جيت-هاب أولًا وأكِّد امتلاكك عنوان البريد الإلكتروني الذي استخدمته في التسجيل. أنشئ مستودعًا لتخزين الملفات. أدخِل في الصندوق Repository name الظاهر في الصفحة الموضحة في الشكل التالي العبارة username.github.io، إذ يمثل username اسم المستخدم، فقد يُدخِل "مازن" الاسم "mazen.github.io" مثلًا، ثم فعِّل بعد ذلك الخيار Initialize this repository with a README وانقر بعدها زر أنشئ مستودعًا create repository. اسحب وأفلت محتوى الموقع ضمن المستودع واحفظ التغييرات. انتقل باستخدام متصفحك إلى الموقع "username.github.io -وفقًا لما اخترته-، وسيعرض محتوى موقعك. ترجمة -وبتصرف- للمقال Publishing your website. اقرأ أيضًا مدخل إلى خادم ويب. مدخل إلى أسماء النطاقات على شبكة الإنترنت. أساسيات تحديد الكلفة المادية الكاملة لبناء موقع ويب
-
صُمم البرنامج "نوبس NOOBS" لتسهيل عملية تثبيت أنظمة التشغيل على راسبيري باي ما أمكن، إذ يمكنك شراء بطاقة ذاكرة microSD ثُبت عليها نوبس مسبقًا من أي موزّع لتجهيزات باي، أو اتباع التعليمات التالية لتثبيت البرنامج على بطاقة ذاكرة خاصة بك. تنزيل نوبس NOOBS لتثبيت نوبس على بطاقة ذاكرة فارغة، عليك تنزيل البرنامج من موقع ويب راسبيري باي على حاسوب قادر على قراءة بطاقة الذاكرة microSD و full-size SD مع محوِّل لبطاقة microSD، ويمكنك استخدام قارئ بطاقات ذاكرة بواجهة USB كذلك. استخدم المتصفح في الوصول إلى موقع التنزيلات الخاص براسبيري باي وانقر على برنامج نوبس المُعلّم بأيقونة راسبيري باي في الصفحة التي يحملها المتصفح، ثم انقر "تنزيل ملف مضغوط Download ZIP" ضمن الفئة "تنزيل نوبس دون اتصال أو عبر الشبكة NOOBS Offline and network install". يستغرق تنزيل نوبس وقتًا وخاصة إن كان الاتصال بالإنترنت بطيئًا. عند انتهاء التنزيل أدخل بطاقة الذاكرة في الحاسوب، وستظهر على شكل سواقة مفردة قابلة للإزالة، وقد تُضطرإلى تهيئتها format أولًا إن لم تظهر بهذا الشكل. خياري تنزيل: لاحظ وجود نسختين قابلتين للتنزيل على صفحة تنزيلات نوبس، هما: NOOBS و NOOBS Lite. تنزِّل النسخة الأولى نوبس ونسخة عن آخر إصدار لنظام التشغيل راسبيان في حزمة واحدة؛ بينما تنزِّل النسخة الثانية نوبس فقط. ما يحتاجه معظم المستخدمين هي النسخة الأولى، فلا تنزل النسخة الثانية إلا إذا كنت تخطط لتثبيت نظام تشغيل آخر غير راسبيان. تُثبَّت النسختان بالطريقة ذاتها كما نشرحها في هذا الملحق. تهيئة بطاقة الذاكرة microSD لتهيئة بطاقة ذاكرة مستخدمة سابقًا لتثبيت نوبس، ينبغي لمستخدمي ويندوز أو ماك أو إس تنزيل أداة تهيئة بطاقة الذاكرة "SD Card Association SD Memory Card Formatter"، ثم تثبيتها، أما بالنسبة لمستخدمي لينوكس، فالأداة "disk management tool" هي المستخدمة في حذف أية تقسيمات على البطاقة، ثم إنشاء جزء وحيد single partition وتهيئته وفق نظام الملفات VFAT، ثم إكمال هذا الدليل. أدخل بطاقة الذاكرة في الحاسوب إن لم تكن قد فعلت ذلك، ثم شغِّل الأداة "SD Card Formatter". ابحث عن بطاقة الذاكرة ضمن القائمة "اختر بطاقةً Select card"، إذ قد تجد أكثر من بطاقة لها نفس اسم بطاقتك إن كنت قد استخدمتها سابقًا مع راسبيري باي، لذلك اختر واحدةً منها في هذه الحالة وتحقق من اختيارك للقرص الصحيح (بطاقة الذاكرة) بالاطلاع على معلومات القرص في قسم "معلومات البطاقة card information" الذي يعرض حجم ونوع بطاقة الذاكرة microSD التي أدخلتها. حاول أن تختار الآخرى إن كانت المعلومات المعروضة ليست صحيحة (ليست معلومات بطاقتك)، وتحقق من صحة المعلومات من جديد حتى تتأكد تمامًا بأنها البطاقة الصحيحة. تحقق كذلك من عمل نسخة احتياطية لأية ملفات مخزنة عليها قد تحتاجها لاحقًا، ثم سمِّ البطاقة "NOOBS" من خلال الصندوق "عنوان وحدة التخزين volume label" وانقر زر "تهيئة format" وأكّد -عندما يُطلب منك ذلك- رغبتك في تهيئة القرص. لن يستغرق خيار التهيئة السريعة "quick format" سوى ثوانٍ معدودة ليكتمل. أغلق بعد ذلك أداة التهيئة. تثبيت نوبس وهي عمليةٌ بسيطة مثل عملية سحب وإفلات. ابحث عن ملف نوبس الذي نزلته مسبقًا وستجده عادةً في مجلد " التنزيلات Downloads". يُدعى هذا الملف "ملف أرشيف Archive file"، ويحتوي نسخًا عن كثيرٍ من الملفات التي ضُغطت ضمنه لتقليل حجمها وتسريع تنزيلها. انقر على الأرشيف نقرًا مزدوجًا لفتحه، ثم اضغط على المفتاحين "CTRL+ A" في نظام ويندوز، أو "⌘+A" في نظام ماك أو إس لاختيار جميع ملفات الأرشيف، ثم اسحب هذه الملفات إلى بطاقة الذاكرة microSD ثم أفلتها وانتظر حتى تكتمل عملية النسخ والتي قد تستمر عدة دقائق. أخرج بطاقة الذاكرة عندما ينتهي نسخ الملفات من الحاسوب وضعها في راسبيري باي. عندما تُقلع باي مرةً أخرى سيُحمّل برنامج نوبس وسيطلب منك اختيار نظام التشغيل الذي تود تثبيته. تثبيت البرامج وإزالتها يأتي مع نظام التشغيل راسيبان Raspbian مجموعةً من البرامج المُختارة من قبل مؤسسة راسبيري باي لكنها طبعًا ليست الوحيدة التي تعمل على راسبيان. سترشدك الأفكار التالية إلى طريقة تصفُّح برامج إضافية وتثبيتها أو إزالتها لتوسيع إمكانيات باي. بُنيت الإرشادات في هذا الملحق على ما شرحناه في المقال الثالث "نظام تشغيل راسبيري باي (راسبيان)" من هذه السلسلة دليل راسبيري باي حول استخدام بعض البرمجيات الأساسية، لذلك من الأفضل العودة إلى هذا الفصل -إن لم تفعل بعد- قبل استخدام الطرق التي سنشرحها في هذا الملحق. سعة بطاقة الذاكرة: تستهلك البرامج الإضافية التي تثبتها مساحةً أكبر على بطاقة الذاكرة. تسمح لك مثلًا بطاقات الذاكرة بحجم 16 جيجابايت أو أكثر بتثبيت برامج أكثر، ويمكنك التحقق من أن بطاقة الذاكرة التي تنوي استخدامها مناسبةٌ لراسبيري باي من خلال موقع دعم راسبيري. تصفح البرامج الموجودة يمكن تصفُّح قائمة البرمجيات المُتاحة لراسبيان، والتي تُعرف باسم مستودعات البرمجيات software repositories من خلال النقر على أيقونة راسبيري والانتقال إلى فئة "تفضيلات Preferences"، ثم النقر على "إضافة/ إزالة البرامج Add/Remove Software". ستظهر نافذة الأداة بعد عدة ثوانٍ. يتضمن الجانب الأيسر للنافذة قائمةً بالفئات تشبه تلك التي تراها في قائمة راسبيري باي. ستعرض لك نافذة إضافة / إزالة البرامج جميع البرمجيات التي تندرج تحت فئة معينة عند النقر عليها؛ ويمكنك أيضًا البحث عن برنامج أو توصيف برنامج بكتابته في صندوق البحث في أعلى يسار النافذة، مثل "محرر نصوص text editor"، أو "ألعاب games"، وستجد نتيجة البحث على هيئة قائمة من البرامج التي حققت معيار البحث من كل الفئات. لمزيدٍ من المعلومات حول أي برنامج منها، انقر عليه ضمن القائمة وستُعرض المعلومات في الفراغ أسفل النافذة. في حال ضمّت فئةٌ من الفئات كثيرًا من البرمجيات المتاحة للتثبيت، سيستغرق ذلك وقتًا أطول من نافذة إضافة/إزالة البرامج لعرضها. تثبيت برنامج فعّل مربع التحقق بجوار البرنامج الذي تريد تثبيته بالنقر عليه. ويمكنك طبعًا النقر على مربعات التحقق قبل مجموعة البرامج التي تحتاجها لكي تثبتها الأداة في نفس الوقت. ستتحول الأيقونة إلى جانب البرنامج الذي تختاره إلى أيقونة صندوق مفتوح وعليه الرمز "+" للإشارة إلى أنه جاهزٌ للتثبيت؛ وعندما تكتمل قائمة البرامج التي تحتاجها انقر على أحد الزرين "OK" أو "Apply"، إذ لا فرق بين الزرين السابقين سوى أنّ الأول يغلق النافذة عند الانتهاء من التثبيت بينما يبقيها الثاني مفتوحة. سيُطلب منك إدخال كلمة المرور للتأكد من هويتك، فلن ترغب بالتأكيد أن يعبث أحد بالبرامج التي تثبتها على باي قد تلاحظ أحيانًا أنّ مجموعة حزم قد جرى تثبيتها مع البرنامج الذي ثبته، إذ تُعرف هذه الحزم بالاعتماديات dependencies ويحتاجها برنامجك للعمل بصورةٍ جيدة، مثل حزمة المؤثرات الصوتية التي تحتاجها الألعاب، أو قاعدة بيانات للعمل مع مخدم ويب. يمكنك الوصول إلى برنامجك بعد اكتمال التثبيت ضمن الفئة التي ينتمي إليها في قائمة راسبيري باي. تذَكر أن الفئات في قائمة راسبيري باي قد تختلف عن الفئات في أداة إضافة / إزالة البرامج، وقد لا تجد اختصارًا لبعض البرامج التي ثبتّها في قائمة راسبيري إطلاقًا والتي تعرف ببرامج سطر الأوامر Command-line software، إذ ينبغي تشغيلها من برنامج الطرفية "Terminal". لمزيدٍ من المعلومات حول سطر الأوامر والطرفية راجع الملحق "C" (واجهة سطر الأوامر). إلغاء تثبيت برنامج لإزالة أو إلغاء تثبيت برنامج، افتح أداة إضافة / إزالة البرامج، ثم ابحث عن البرنامج الذي تريد إلغاء تثبيته وألغِ تفعيل مربع التحقق إلى جواره بالنقر عليه؛ كما يمكنك استخدام صندوق البحث لإيجاد البرنامج المطلوب؛ وتستطيع كذلك إلغاء تثبيت عدة برامج معًا بالنقر على مربع التحقق بجوار كل منها وإلغاء تفعيله، وسيتغير عندها شكل الأيقونة إلى صندوق مفتوح بجواره سلة محذوفات للإشارة بأن هذا البرنامج سيُحذف أو يُلغى تثبيته. انقر بعد ذلك على أحد الزرين "OK" أو "Apply" لتبدأ العملية، وسيطلب منك إدخال كلمة المرور إن لم تكن قد أدخلتها لسببٍ ما خلال الدقائق القليلة الماضية، كما قد يُطلب منك تأكيد عملية إلغاء تثبيت البرنامج وأية اعتماديات مرتبطة به أيضًا. سيختفي البرنامج من قائمة باي عند اكتمال عملية إلغاء التثبيت، ولن تُحذف طبعًا أية ملفات كنت قد أنشأتها بهذا البرنامج، مثل الرسوميات أو الصور أو المستندات وغيرها. ترجمة -وبتصرف- للملحقين Installing NOOBS to a microSD card و Installing and uninstalling software من كتاب The Official Raspberry Pi Beginner's Guide اقرأ أيضًا المقال السابق: ربط كاميرا مع لوحة راسبيري باي وتشغيلها تجميع راسبيري باي والتحضير لاستعماله ما هو حاسوب راسبيري باي Raspberry Pi؟
-
تستطيع التقاط صورٍ عالية الدقة وتسجيل مقاطع فيديو باستخدام تجهيزة الكاميرا، التي تتصل مع باي Pi Camera Module وتساعدك في إنشاء مشاريع محتوًى بصري مميزة. إذا كنت مهتمًا بإنتاج محتوًى بصري مهم، أو "رؤية حاسوبية Computer Vision" كما تُعرف في حقل الروبوت، فستكون كاميرا باي بدايةً جيدة. تظهر التجهيزة على شكل دارة صغيرة مربعة الشكل لها كابل شريطي ribbon cable يمكن وصله إلى راسبيري باي عبر المنفذ التسلسلي للكاميرا Camera Serial Interface -أو اختصارًا CSI-؛ مما يسمح لباي بالتقاط صورٍ ثابتة أو متحركة بدقةٍ عالية للاستخدامات المتنوعة. تُعرف كاميرا باي حتى لحظة تحرير هذه النسخة من الكتاب بأنها التجهيزة "v2" أو تجهيزة النسخة 2.1 المبنية على حساس الصورة "Sony IMX219"، وهو نفسه الحساس الذي قد تجده خلف هاتفك الذكي أو جهازك اللوحي. تصل دقة الحساس إلى 8 ميغا بكسل وهذا يعني أنه قادرٌ على التقاط صورٍ مكونة من 8 ملايين بيكسل pixel موزعةٍ إلى 3280 بيكسل عرضًا و2464 بيكسل طولًا (جداء الرقمين السابقين سيتجاوز قليلًا 8 ملايين). يمكن للكاميرا التقاط مقاطع فيديو إضافةً إلى الصور الثابتة وبدقة Full HD التي تعتمدها معظم أجهزة التلفاز بمعدلٍ يصل إلى 30 إطارًا في الثانية ليساعدك على إظهار حركةٍ سلسةٍ ويعزّز إمكانية تأثيرات الحركة البطيئة. يمكن رفع معدل الالتقاط إلى 60 إطارًا في الثانية بتخفيض الدقة إلى 720p وإلى 90 إطار في الثانية بتخفيض الدقة أكثر إلى 480p؛ وهي دقة منظومة VGA للشاشات التقليدية. تثبيت كاميرا راسبيري باي مثل تجهيزة إضافية، لا بدّ من فصل التغذية الكهربائية عن باي وسحب كابل التغذية قبل وصل تجهيزة الكاميرا. أوقف تشغيل راسبيري باي بالنقر على أيقونة راسبيري باي، ثم اختيار الأمر "إيقاف التشغيل Shutdown". انتظر حتى تتوقف باي عن العمل، ثم انزع كابل التغذية الكهربائية. افتح علبة الكاميرا وستجد دارةً صغيرةً مربعة هي الكاميرا نفسها وكابلًا شريطيًا سيكون متصلًا بالكاميرا في معظم الحالات. اقلب الكاميرا بحيث تواجه عدستها الأرض إذا لم يكن الكابل متصلًا بها، ثم ابحث عن وصلةٍ بلاستيكية مسطحة لها طرفان ناتئان قليلًا. اضغط على النتوئين للداخل واسحبهما للخلف، فيتحرك معك جزءٌ من الوصلة إلى الخارج. ازلق الكابل الشريطي في الوصلة بحيث تكون حافته الفضية إلى الأسفل والقطعة الزرقاء لطرفه نحو الأعلى، ثم ادفعه جيدًا في الوصلة وأعِد الجزء الذي سحبته إلى مكانه. يمكنك وصل أي من طرفي الكابل الشريطي إلى الكاميرا وتأكد عند وصله بأنه مركبٌ جيدًا، حيث يجب ألا يخرج من مكانه إذا حاولت سحبه. شكل 1-8 توصيل الكابل الشريطي إلى الكاميرا سنركِّب الطرف الآخر على باي بنفس الطريقة. جد أولًا منفذ الكاميرا "CSI" وارفع الغطاء قليلًا إلى الأعلى، وقد يكون من الأسهل لو أخرجت باي من حاضنتها إن كنت تستخدم واحدة. ازلق كابل الكاميرا في الوضعية التي يكون فيها منفذ HDM لراسبيري باي متجهًا نحوك، ثم ادفع الغطاء بلطف إلى مكانه. تأكد عند وصل الكابل بأنه مركبٌ جيدًا، حيث يجب ألا يخرج من مكانه إذا حاولت سحبه. شكل 2-8 توصيل الكابل الشريطي للكاميرا مع منفذ CSI لباي يأتي مع عدسة الكاميرا رقعةٌ بلاستيكية زرقاء لحمايتها من الخدش أثناء التصنيع والشحن والتركيب. جد النتوء الصغير على طرف الرقعة وانتزعه بلطف لتصبح الكاميرا جاهزةً للاستخدام. صل التغذية الكهربائية مجددًا إلى باي واتركها حتى تحمّل راسبيان. لا بدّ من إخبار باي أنك وصلت الكاميرا لتتمكن من استخدامها. انقر على أيقونة راسبيري، ثم انتقل إلى فئة "تفضيلات preferences" وانقر على "إعداد راسبيري باي Raspberry Pi Configuration". انقر على نافذة "واجهات interfaces" في نافذة الأداة السابقة عندما يكتمل تحميلها، ثم ابحث عن "كاميرا Camera" وانقر على زر الخيارات الدائري إلى يسار الكلمة "تمكين Enabled" لتفعيله. انقر الزر "OK"، ستطلب منك الأداة إذنًا لإعادة تشغيل باي. دعها تفعل ذلك وستصبح الكاميرا جاهزةً عندما يقلع النظام من جديد. شكل 3-8 لا بدّ من تفعيل الكاميرا باستخدام أداة إعداد راسبيري باي اختبار الكاميرا للتأكد من تثبيت الكاميرا وتفعيل واجهتها على نحوٍ صحيح، يمكن استخدام أداة الصور الثابتة rapistill وأداة الفيديو raspivid المصممتين لالتقاط الصور من خلال تجهيزة الكاميرا باستخدام واجهة سطر الأوامر command-line interface -أو اختصارًا CLI-. لن تجد هاتين الأداتين مثل بقية البرامج ضمن قائمة راسبيري باي الرئيسية بل ينبغي تحميلهما من برنامج الطرفية "Terminal"، الذي تجده في فئة "البرامج الملحقة Accessories". بالنقر على البرنامج ستظهر نافذةٌ لها خلفيةٌ سوداء وأسطرٌ باللونين الأزرق والأخضر تمثًِل الطرفية التي تسمح لك بالتعامل مع واجهة سطر الأوامر. شكل 4-8 نافذة برنامج الطرفية Terminal التي تسمح لك بالوصول إلى سطر الأوامر اكتب الأمر التالي في الطرفية لاختبار الكاميرا: raspistill -o test.jpg وبمجرد الضغط على المفتاح Enter ستظهر صورةٌ كبيرة لما تعرضه الكاميرا على الشاشة، ويُعرف ذلك باسم العرض المباشر والذي يستمر خمس ثوانٍ ما لم تحدد خلاف ذلك. تلتقط الكاميرا بعد 5 ثوان صورةً ثابتة لما تعرضه وتخزّنها في المجلد "home" باسم test.jpg. إذا أردت التقاط صورةٍ أخرى، نفِّذ التعليمة السابقة مجددًا ولا تنس تغيير اسم ملف الخرج بعد الخيار o- وإلا ستخزن الصورة الجديدة فوق القديمة. شكل 5-8 العرض المباشر للكاميرا إذا كانت صورة العرض المباشر مقلوبةً رأسًا على عقب، فعليك تنبيه raspistil بأن الكاميرا مقلوبة. صُممت تجهيزة الكاميرا لكي يكون الكابل الشريطي خارجًا من الحافة السفلية؛ فإذا كان خارجًا من أحد جانبي أو من أعلى باي كما هو الحال في بعض الكاميرات التي ينتجها طرفٌ ثالث، فعليك تدوير الصورة 90 أو 180 أو 270 درجة باستخدام الخيار rot-. استخدم ببساطة الأمر التالي إذا خرجت الكاميرا من الأعلى: raspistill -rot 180 -o test.jpg بينما لو خرجت الكاميرا مع الشريط من الجانب الأيمن، دوّر الصورة 90 درجة؛ ودوّرها 270 درجة، إذا خرجت من الجانب الأيسر؛ وإذا كانت الزاوية الأصلية لالتقاط الصورة غير صحيحة استخدم الخيار rot- لتدويرها إلى وضعها الصحيح. لرؤية الصورة الملتقطة: افتح برنامج "مدير الملفات File Manager" من قائمة راسبيري فئة "برامج ملحقة Accessories"، ثم انتقل إلى المجلد "home/Pi" وستجد الصورة باسم "test.jpg". انقر على الصورة نقرًا مزدوجًا لفتحها ضمن برنامج "عارض الصور image viewer". تستطيع بالطبع إرسال الصورة عبر البريد الإلكتروني؛ أو رفعها إلى موقع ويب؛ أو نقلها إلى وسيط تخزين خارجي. شكل 6-8 عرض الصورة الملتقطة تعرف على مكتبة picamera يعدّ استخدام مكتبة بايثون picamera الطريقة الأكثر مرونة في التحكم بتجهيزة كاميرا باي سواءً بالعرض المباشر أو بالتقاط الصور والفيديوهات، كما تسمح لك بدمج ما التقطته في برامجك الخاصة، وكذلك مع البرامج التي تستخدم المنصة GPIO من خلال مكتبة GPIO Zero. أغلق برنامج الطرفية إذا كان مفتوحًا بالنقر على زر الإغلاق X في أعلى يمين النافذة، ثم افتح ثوني بالطريقة المعتادة. أنشئ مشروعًا جديدًا واحفظه باسم "Camera". أدرج المكتبات التي يحتاجها برنامجك من خلال كتابة الأسطر التالية: from picamera import PiCamera from time import sleep camera = PiCamera() يتيح لك سطر الشيفرة الأخير التحكم بتجهيزة الكاميرا من خلال الدالة camera. لتبدأ العرض، اكتب الشيفرة التالية: camera.start_preview() sleep(10) camera.stop_preview() انقر على أيقونة التشغيل "Run" وسيختفي سطح المكتب ويحل مكانه عرضٌ مباشرٌ على كامل الشاشة لما تراه الكاميرا. حاول تحريك الكاميرا أو التلويح بيدك أمام عدساتها وستلاحظ تغيُّر الصورة المعروضة على الشاشة لتطابق التغيير الجاري. يتوقف العرض وينتهي تنفيذ برنامجك بعد عشر ثوانٍ. شكل 7-8 عرض ما تراه الكاميرا على كامل الشاشة. دوّر الصورة إذا ظهرت بزاوية عرضٍ خاطئة حتى تحصل على الاتجاه الصحيح وذلك باستخدام سطر الشيفرة التالي: camera.rotation = 180 بوضعه تحت السطر: camera = PiCamera() إذا كان العرض مقلوبًا رأسًا على عقب، ستجعله تعليمة الدوران السابقة بوضعه الصحيح. تسمح لك تعليمة الدوران بتدوير الصورة بزاوية 90 و 180 و 270 درجة، ويتعلق اختيار زاوية الدوران الصحيحة بمكان خروج كابل الكاميرا إذا كان من يمين تجهيزة الكاميرا أو أعلاها وهكذا. إذًا، تذكّر كتابة تعليمة دوران الصورة في بداية كل برنامج لتفادي العرض الخاطئ. التقاط صور ثابتة يتوجب تعديل برنامجك لالتقاط صورة وتخزينها بدلًا من عرض ما تراه الكاميرا فقط. ابدأ أولًا بتعديل قيمة التأخير الزمني (10)sleep إلى (5)sleep، ثم اكتب السطر التالي بعدها مباشرةً: camera.capture('/home/pi/Desktop/image.jpg') تُخزّن الدالة صورةً ثابتة، ولا بدّ أن تحدد ضمنها اسم الصورة التي تلتقطها ومكان تخزينها. لاحظ أنك تخزن الصورة في الشيفرة السابقة على سطح المكتب، ابحث عنها في جوار "سلة المحذوفات Wastebasket". ابعد نافذة ثوني إذا كانت تعيق الرؤية، ثم انقر على ملف الصورة التي التقطها برنامجك لتراها. تهانينا، لقد كتبت أولى برامجك للكاميرا! شكل 8-8 فتح الصورة التي التقطتها التقاط مقاطع فيديو تستطيع أيضًا تصوير مقاطع فيديو وتخزينها. احذف كل الشيفرة بين الدالتين ()camera.start_preview و()camera.stop_preview، ثم اكتب الشيفرة التالية تحت الدالة الأولى: camera.start_recording('/home/pi/Desktop/video.h264') sleep(10) camera.stop_recording() تعرض الكاميرا ما تراه كما في الحالة السابقة لكنها تسجل في نفس الوقت مقطع فيديو في ملفٍ على سطح المكتب. ستستمر العملية 10 ثوان، لذلك قد تفكر في فعل شيءٍ ما أمام الكاميرا ليبدو الفيديو أكثر تشويقًا، وسيتوقف بعد ذلك التسجيل. يمكنك حينها العودة إلى سطح المكتب ومتابعة الفيديو، حيث ستجده باسم "video.h264"، وستظهر رسالةٌ لطيفة على الطرفية عند انتهاء عرض الفيديو. تهانينا، ستلتقط من الآن فصاعدًا مقاطع فيديو باستخدام كاميرا باي! زر لتحريك الرسوميات سنحاول تصميم مشروعٍ مميز اعتمادًا على ما تعلمته في هذا المقال وخبرتك التي اكتسبتها في توصيل المكوّنات الفيزيائية إلى أرجل المنصة GPIO. سنُصمم استوديو خاص بك لتحريك الرسوميات والصور؛ حيث تمثّل تحريك الرسوميات عملية التقاط الكثير من الصور المتلاحقة لغرضٍ ما أو لشخص، ومن ثم تحريك الصور بتتابعٍ معين ليظهر الغرض وكأنه يتحرك. وبالطبع سترى أن الغرض ساكن إذا نظرت إلى كل صورةٍ على حدى؛ ولكن إذا عرضتها على نحوٍ متتابع بسرعة، فسيبدو وكأنه يتحرك وبالسرعة التي تريد. ستحتاج في هذا المشروع إلى: زر كبس Push button. لوحة اختبار. أسلاك بوصلات طرفية "M2M". زوج أسلاك بوصلات طرفية "M2F". أسلاك بوصلات "F2F"، إذا لم تستخدم لوحة الاختبار، وبالطبع سيصعب عليك عندها ضغط الزر براحة. إذا أردت أن تتذكر أية معلومات عن هذه المكوّنات، عليك مراجعة مقال "البرمجة الفيزيائية باستخدام سكراتش وبايثون". ستحتاج الآن إلى أغراض لتحريكها والتي قد تكون أي شيء، مثل لعبة أو زهرة أو شخصية. جمِّع الدارة أولًا بتثبيت الزر على لوحة الاختبار، ثم صِل مسار التغذية السالب للوحة مع أحد أرجل الأرضية GND للمنصة GPIO بواسطة سلك M2F. استخدم سلك M2M لوصل أحد أرجل الزر بمسار التغذية السالب للوحة وسلك M2F لوصل رجله الأخرى بالرجل GP2 للمنصة GPIO. الشكل 9-8 وصل الزر إلى أحد أرجل المنصة GPIO أنشئ مشروعًا جديدًا في ثوني واحفظه باسم "Stop Motion"، وابدأ بإدراج المكتبات اللازمة لعمل الكاميرا ومنصة GPIO: from picamera import PiCamera from gpiozero import Button camera = PiCamera() button = Button(2) اكتب الآن الشيفرة التالية: camera.start_preview() button.wait_for_press() camera.capture('/home/pi/Desktop/image.jpg') camera.stop_preview() انقر على أيقونة التشغيل وسيظهر على الشاشة العرض المباشر لما تراه الكاميرا؛ حيث سيبقى العرض على الشاشة مستمرًا حتى تضغط على الزر ليختفي العرض المباشر وينتهي برنامجك بعد أن يخزّن الصورة الملتقطة على سطح المكتب. ابحث عن الصورة التي تحمل الاسم "image.jpg" وحاول فتحها للتأكد أن البرنامج يعمل على مايرام. يتطلب تحريك الرسوميات إنشاء كثيرٍ من الصور لتعطي انطباعًا بالحركة عندما تعرض على نحوٍ متتالي، ولهذا ستحتاج إلى مجلدٍ خاص على سطح المكتب لتخزين جميع هذه الصور. انقر على سطح المكتب بالزر اليميني في أي مكانٍ فارغ، ثم اختر الأمر "إنشاء Create New" ثم "مجلد Folder" وسمِّه "animation" (استخدم أحرف صغيرةً بالكامل)، ثم انقر الزر "OK". شكل 10-8 إنشاء مجلد جديد لتخزين الصور التي تلتقطها الكاميرا. ليس مريحًا إعادة تشغيل برنامجك في كل مرة تلتقط فيها صورة، لذا لا بدّ من تغييره ليستخدم حلقة. وعلى خلاف الحلقات التي استخدمناها سابقًا ستحتاج إلى حلقةٍ تنهي العملية بسلاسة؛ فلو أوقفت البرنامج والكاميرا في حالة العرض المباشر، فلن تكون قادرًا على الوصول إلى سطح المكتب بعده! ستحتاج لإنجاز الأمر إلى تعليمتي try وexcept. احذف كل الشيفرة التي تأتي بعد الدالة camera.start_preview، ثم اكتب: frame = 1 تُنشئ هذه التعليمة المتغير الجديد frame وتسند له القيمة 1. يخزِّن البرنامج في هذا المتغير رقم الإطار الحالي وسنستخدمه للتأكُّد من تخزين ملفٍ جديد كل مرة وإلا ستُخزن الصور فوق بعضها كلما ضُغط الزر. سننشئ الآن الحلقة على النحو التالي: while True: try: تخبر التعليمة try بايثون بأن ينفذ ما بداخلها من التعليمات، والتي ستكون تعليمات التقاط الصورة: button.wait_for_press() camera.capture('/home/pi/Desktop/animation/frame%03d.jpg' % frame) frame += 1 نلفت انتباهك إلى عدة حيلٍ ذكية في الشيفرة السابقة وأولها استخدام التعبير 03d%؛ والذي يسمح بإضافة أصفارٍ إلى عددٍ ليُكتب بثلاث خانات؛ أي سيُكتب العدد "1" على النحو التالي "001"، ويكتب العدد "12" على النحو التالي "012". يساعدك هذا الحل على تخزين الصورة وفق الترتيب الصحيح دون أن تخزّن فوق بعضها. أما التعليمة frame% في آخر السطر ستجعل بايثون يستخدم رقم الإطار اسمًا لملف الصورة الملتقطة. يزيد السطر الذي يليه قيمة المتغير frame بمقدار واحد فستتحول قيمته من 1 إلى 2 عند أول ضغطة على الزر وهكذا. سنستخدم التعليمة except لتحديد نهاية عملية التقاط الصور وتخزينها. اكتب الشيفرة التالية منتبهًا للإزاحة؛ ولذلك أزِل مستوًى واحدًا من المسافة البادئة في السطر الأول حتى يعرف بايثون أنها ليست جزءًا من try: except KeyboardInterrupt: camera.stop_preview() break سيبدو البرنامج الكامل على النحو التالي: from picamera import PiCamera from time import sleep from gpiozero import Button camera = PiCamera() button = Button(2) camera.start_preview() frame = 1 while True: try: button.wait_for_press() camera.capture('/home/pi/Desktop/animation/frame%03d.jpg' % frame) frame += 1 except KeyboardInterrupt: camera.stop_preview() break انقر على أيقونة التشغيل "Run"، ثم اضغط مفتاحي لوحة المفاتيح "Ctrl" و"C". ليس بالضرورة ضغط المفتاحين معًا فيكفي ضغط "Ctrl" باستمرار ثم ضغط "C" وتحرير المفتاحين بعدها. ينفِّذ هذان الزران معًا ما يُسمى مقاطعة interrupt مصدرها لوحة المفاتيح لإيقاف عمل البرنامج. وهذا ما يفعله تمامًا السطر: except KeyboardInterrupt: حيث تتوقف عملية التقاط الصور مباشرةً عندما ننفِّذ طلب مقاطعةً بواسطة لوحة المفاتيح؛ وإلا ستعيق نافذة العرض المباشر للكاميرا الوصول إلى سطح المكتب إذا أنهيت البرنامج بالنقر على أيقونة الإيقاف "Stop". على الرغم من تنفيذ بايثون لأية شيفرات صحيحة، لكن في حالتنا يأتي أمر الإيقاف من الشيفرة التي ستنهي العرض المباشر للكاميرا ومن ثم توقِف البرنامج على النحو الصحيح. وهكذا ستكون مستعدًا الآن لتحريك الرسوميات. ثبِّت الكاميرا في مكانٍ مناسب لالتقاط صورة الغرض الذي تريد تحريكه، وتأكد بأنه ثابت لا يتحرك، فإذا تحركت الكاميرا ستُفسد العملية. ضع الغرض في موقعه الأولي، ثم انقر أيقونة التشغيل وراقب العرض المباشر للكاميرا لتتأكد أن كل شيء في مكانه الصحيح. اضغط الزر لالتقاط أول صورة (أول إطار)، ثم حرِّك الغرض بلطف؛ فكلما كان اختلاف الموقع بين الصورتين ضئيًلا كان الرسم المتحرك الناتج أكثر نعومة. اضغط الزر مرةً أخرى لالتقاط الإطار الثاني وحرِّك الغرض وهكذا كرّر العملية حتى تنتهي. كلما زاد عدد الصور المُلتقطة، كلما زادت مدة الرسم المتحرك الذي تصممه. اضغط مفتاحي لوحة المفاتيح "Ctrl+C" لإيقاف البرنامج ثم افتح المجلد "animation" على سطح المكتب بالنقر المزدوج عليه. تحقق من أي صورة بالنقر عليها نقرًا مزدوجًا واستعراض تفاصيلها. شكل 11-8 الصور الملتقطة في المجلد المخصص لها ليس لدينا حتى اللحظة سوى مجلدٍ ممتلئ بالصور الثابتة ولا بدّ من تحويلها إلى فيديو لكي ننشئ الرسم المتحرك الذي نريده. لذلك، انقر على أيقونة باي وانتقل إلى فئة "البرامج الملحقة Accessories"، ثم انقر على برنامج الطرفية "terminal" التي تمثّل واجهة سطر الأوامر(ستُناقش بمزيدٍ من التفصيل في الملحق "C"). بعد أن يكتمل تحميل برنامج الطرفية استخدم الأمر التالي للانتقال إلى المجلد "animation" على سطح المكتب: cd Desktop/animation وانتبه أن يكون الحرف D في كلمة Desktop كبيرًا؛ لأن راسبيان حساسٌ لحالة الأحرف فلن يعمل أي أمر إذا لم تكتبه تمامًا كما هو في الأصل. عندما تنتقل إلى المجلد المطلوب اكتب الأمر التالي: avconv -r 1 -i frame%03d.jpg -r 10 animation.h264 يحمل الأمر السابق البرنامج avconv، الذي يقرأ الصور الثابتة من المجلد ويحوّلها إلى فيديو يُدعى animation.h264. قد يستغرق الأمر عدة دقائق وفقًا لعدد الصور الثابتة في المجلد؛ وستعرف أنه انتهى من عمله عندما ترى محث الطرفية يومض في سطرٍ جديد. ابحث عن الملف "animation.h264" في مجلد الصور وانقر عليه نقرًا مزدوجًا لتشغيله، كما يمكنك استخدام الطرفية بكتابة الأمر التالي: omxplayer animation.h264 بمجرد تحميل الفيديو سترى ما أنجزته. تهانينا، لقد حولت باي إلى أداة لإنشاء الرسوم المتحركة. إذا رأيت أن الفيديو سريع كثيرًا أو بطيء كثيرًا، غيِّر الخيار r 10- في تعليمة تشغيل البرنامج avconv زيادةً أو نقصانًا؛ حيث يتحكم هذا الخيار بمعدل الإطارات المعروضة في الثانية. كلما زاد المعدل كلما كان الفيديو أكثر دقة وسلاسة لكنه سيعرض مشاهدًا أقل في حجم محدد للمقطع. والعكس صحيح، فنقصان المعدل يجعل الملف أقل نعومة لكنه سيعرض مشاهدًا أكثر في نفس الحجم. إذا أردت أخيرًا حفظ مقطع الفيديو انقله إلى المجلد "فيديوهات Videos" وإلا سيُسجَّل مقطع فيديو جديد فوقه في كل مرةٍ تشغِّل فيها برنامجك. الإعدادات المتقدمة للكاميرا إذا أردت التمتُّع بقدرةٍ أكبر على التحكم بإعدادات تجهيزة كاميرا راسبيري باي، يمكنك الاستفادة من مكتبة picamera في بايثون للوصول إلى الإعدادات المختلفة للكاميرا، وقد فصلنا فيما يلي هذه الإعدادات مع قيمها الافتراضية لتستخدمها لاحقًا في برامجك: إعداد الموازنة التلقائية للون الأبيض camera.awb_mode يضبط هذا الإعداد الموازنة التلقائية للون الأبيض في الكاميرا: camera.awb_mode = 'auto’ ويُضبط على أحد الخيارات التالية: off auto افتراضي. sunlight cloudy shade tungsten fluorescent incandescent flash horizon بدِّل بين الخيارات السابقة إذا رأيت الصورة مائلةً للزرقة أو الاصفرار. إعداد الإضاءة camera.brightness يحدّد مقدار إضاءة الصورة الملتقطة. camera.brightness = 50 حيث تكون الصورة مظلمةً عندما تكون قيمة الإعداد 0 وشديدة الإضاءة (أقرب إلى اللون الأبيض) عندما تكون قيمته 100. إعداد التأثيرات اللونية camera.color_effects يغيّر هذا الإعداد التأثيرات اللونية التي تستخدمها الكاميرا، حيث يُترك هذا الإعداد عادةً دون تغيير. camera.color_effetcs = None لكن إن زوّدت الإعداد بزوجٍ من الأرقام، سيغير ذلك طريقة تسجيل الكاميرا للألوان. حاول أن تضع القيمة (128،128) لإنتاج صورٍ بالأبيض والأسود. إعداد وضوح الصورة camera.contrast يضبط هذا الإعداد وضوح الصورة؛ حيث تجعل القيم العالية الصورة أكثر حيوية؛ بينما تجعل القيم المنخفضة الصورة باهتةً جدًا. يمكنك استخدام قيم بين 100- وهي القيمة الدنيا و 100 وهي أعلى قيمة. camera.contrast = 0 إعداد القص camera.crop يسمح لك بقص أجزاءٍ من الصورة من الأطراف أو الأعلى والتقاط الجزء الذي تريده من الصورة. camera.crop = (0.0, 0.0, 1.0, 1.0) حيث تمثّل الأرقام ما بين القوسين إحداثيات X و Y والعرض والارتفاع. تُلتقط الصورة افتراضيًا بأكملها، لكن إن أردت رؤية تأثير هذا الإعداد، حاول تغيير آخر قيمتين إلى 0.5- و 0.5. إعداد التعويضات camera.exposure_compensation يضبط يدويًا كمية الضوء الواصل إلى حساس الكاميرا الضوئي عند التقاط الصورة. camera.exposure_compensation = 0 وعلى خلاف تغيير السطوع brightness يتحكم هذا الإعداد بالكاميرا نفسها وليس بالصورة، ويأخذ قيمه بين 25- (معتمٌ جدًا) إلى 25 (ساطع جدًا). إعداد درجة الإضاءة camera.exposure_mode يضبط نمط التعرض الضوئي exposure (نمط تحديد كمية الضوء التي تصل إلى الحساس الضوئي للكاميرا) أو المنطق الذي تتبعه الكاميرا في تحديد هذه الكمية. camera.exposure_mode = ‘auto’ يأخذ هذا الإعداد هذه القيم: off auto افتراضي night backlight spotlight sports snow beach verylong fixedfps antishake fireworks إعداد معدل التقاط الإطارات camera.framerate يحدِّد عدد الصور التي تلتقطها الكاميرا في الثانية عند تصوير مقطع فيديو أو ما يسمى معدل التقاط الإطارات. camera.framerate = 30 تسمح لك المعدلات العالية بالتقاط فيديوهات أكثر نعومة، لكنها تستهلك حجمًا أكبر في الذاكرة. وبالتالي يرتبط المعدل الالتقاط العالي بانخفاض الدقة المستخدمة التي يمكن التحكم بها أيضًا من خلال الإعداد "camera.resolution". إعداد القلب الأفقي camera.hflip camera.hflip = False يقلب هذا الخيار الصورة الملتقطة أفقيًا أو بالنسبة للمحور X عندما يأخذ القيمة True. إعداد التأثيرات camera.image_effect يطبق هذا الإعداد مجالًا من التأثيرات على تيار الفيديو والتي ستظهر في العرض المباشر وفي الصور والفيديوهات المخزّنة. camera.image_effect = ‘none’ هذه التأثيرات هي: blur cartoon colorbalance colorpoint colorswap deinterlace1 deinterlace2 denoise emboss film gpen hatch negative none oilpaint pastel posterise saturation sketch solarize washedout watercolor إعداد camera.ISO يغيّر إعدادات ISO للكاميرا والتي تؤثر على حساسيتها للضوء. camera.ISO = 0 تضبط الكاميرا هذا الإعداد تلقائيًا وفقًا لكمية الضوء المتاحة. كما يمكنك ضبطه يدويًا باختيار أحد القيم التالية: 100 أو 200 أو 320 أو 400 أو 500 أو 640 أو 800؛ وكلما زادت القيمة تحسَّن أداء الكاميرا في ظروف الإضاءة المنخفضة؛ لكن ستزداد في المقابل خشونة الصور أو الفيديوهات الملتقطة. إعداد camera.meter_mode يتحكم بكيفية تحديد الكاميرا لكمية الضوء المتاح عندما تضبط مقدار تعرضها للضوء. camera.meter_mode = ‘average’ تقسِّم الكاميرا افتراضيًا كمية الضوء التي تصلها بالتساوي على كامل الصورة. وإليك بقية الخيارات: backlit matrix spot إعداد الدقة camera.resolution يضبط هذا الإعداد دقة الصورة أو الفيديو المُلتقط على هيئة زوجٍ من الأعداد يمثّلان العرض والارتفاع. camera.resolution = (1920,1080) يُساعدك اختيار دقةٍ منخفضة على توفير مساحة التخزين وزيادة معدل الالتقاط؛ بينما تسمح لك الدقة العالية في زيادة جودة الصورة لكنها تستهلك مساحة تخزينٍ أكبر. إعداد التدوير camera.rotation يتحكم بزاوية تدوير الصورة. camera.rotation = 0 يأخذ هذا الإعداد قيمًا من 0 درجة مرورًا بالزاوية 90 و 180 و 270 رجوعًا إلى 0. استخدم هذا الخيار عندما لا تكون قادرًا على ضبط موقع الكاميرا وخرج الكابل من أسفل التجهيزة. إعداد الإشباع camera.saturation يضبط هذا الإعداد درجة إشباع الصورة أو درجة وضوح الألوان ويأخذ قيمًا بين 100- و 100. camera.saturation = 0 إعداد الحدة camera.sharpness يضبط هذا الإعداد حدة تمايز ألوان الصورة ويأخذ قيمًا بين 100- و 100. camera.sharpness = 0 إعداد سرعة الغالق camera.shutter_speed يحدد سرعة فتح وإغلاق غالق الكاميرا shutter عند التقاط صورة أو فيديو. camera.shutter_speed = 0 يمكن ضبط هذا الإعداد يدويًا بواحدة الميكرو ثانية، وكلما زادت مدة بقاء الغالق مفتوحًا كان ذلك أفضل للبيئات المنخفضة الإضاءة والعكس صحيح في البيئات عالية السطوع؛ ويفضل أن يبقى هذا الخيار على وضعه الافتراضي بحيث يُضبط من قِبل الكاميرا تلقائيًا. إعداد القلب العمودي camera.vflip يقلب هذا الخيار الصورة الملتقطة عموديًا أو بالنسبة للمحور Y عندما يأخذ القيمة True. camera.vflip= False إعداد التثبيت camera.video_stabilization يفعِّل هذا الخيار تقنية تثبيت الفيديو عندما يأخذ القيمة True. camera.video_stabilization = False فعّل هذا الخيار عندما تتحرك الكاميرا أثناء التسجيل كأن تكون مرتبطة بروبوت أو محمولة باليد، وذلك لتخفيف الاهتزازات في مقطع الفيديو الذي تصوره. يمكنك الاطلاع على مزيدٍ من المعلومات عن الإعدادات السابقة والإعدادات التي لم نذكرها على الموقع الرسمي للمكتبة picamera ترجمة -وبتصرف- للفصل الثامن "The Raspberry Pi Camera Module" من كتاب The official Raspberry Pi beginner's guide. اقرأ أيضًا المقال السابق: الحوسبة الفيزيائية: برمجة راسبيري باي مع لوحة سنس هات Sense HAT بدء استخدام راسبيري باي تعرف على جهاز راسبيري باي Raspberry Pi تجميع راسبيري باي والتحضير لاستعماله
-
تُعد سنس هات Sense HAT، التي اسُتخدمت في محطة الفضاء الدولية، لوحةً إلكترونيةً مستقلة ومتعددة الوظائف تُضاف إلى راسبيري باي عبر المنصة GPIO، ومزُوّدة بحسّاسات sensors ومصفوفة عرض ضوئية LED matrix display. تُدعم أجهزة راسبيري باي Raspberry Pi بنوع خاص من اللوحات الإلكترونية المضافة التي تُدعى بالتجهيزات المتصلة من الأعلى Hardware attached on top -أواختصارًا HAT-، والتي يمكنها إضافة أي شيء إلى راسبيري باي باي ابتداءً من المايكروفون مرورًا بالأضواء والمرحّلات Relays وحتى الشاشات. تُعد سنس هات من أكثر تجهيزات هات فائدةً وقد صّممت خصيصًا لمهمة الفضاء أسترو باي Astro Pi، وهي مهمةٌ مشتركةٌ بين مؤسسة راسبيري باي ووكالة فضاء المملكة المتحدة ووكالة الفضاء الأوروبية، والتي كانت قد اطّلعت على تجهيزات هات المُخصصة لراسبيري واختارت سنس هات لتنقلها إلى محطة الفضاء الدولية مع الصاروخ الذي حمل معدات المختبر المداري "Cygnus"؛ ولا تزال سنس هات التي لقبها رواد الفضاء "إد ED" و"إيزي Izzy" تُنفِّذ الشيفرات وتُجري اختبارات علمية يُساهم بها أطفال المدارس من كل أنحاء أوروبا. يمكنك الحصول على التجهيزة سنس هات نفسها لدى معظم موزعي راسبيري باي، كما يمكنك استخدام برمجيات تحاكي عمل سنس هات إن لم تشأ شراء واحدة. تعرف على سنس هات سنس هات هي لوحةٌ إلكترونيةٌ مُضافةٌ متعددة الوظائف تُوصل براسبيري باي، وتضم اللوحة مصفوفةً أبعادها 8X8 من المؤشرات الضوئية الحمراء والخضراء والزرقاء RGB القابلة للبرمجة والتي يمكن التحكم بها لإنتاج أي لون تقريبًا من ملايين الألوان المتاحة، إضافةً إلى متحكّم بمقبض ألعاب Joystick بخمس وجهات وستة حساسات مدمجة، هي: جيروسكوب Gyroscope، الذي يتحسس للتغيُّرات في زاوية الدوران مع الزمن، أو كما يُعرف تقنيًا بالسرعة الزاويّة angular velocity، وذلك بتعقب اتجاه حقل الجاذبية للأرض، وهو الحقل الناتج عن قوة الجاذبية التي تشد الأشياء إلى مركز الأرض. ببساطة، يستشعر الجيروسكوب دوران سنس هات بالنسبة لسطح الأرض ويحدّد سرعة دورانها. مقياس التسارع Accelerometer: خلافًا للجيروسكوب الذي يقيس تغيرات زاوية الحركة بالنسبة لسطح الأرض يقيس مقياس التسارع القوة المسببة لتسارع الحركة في الاتجاهات المختلفة، وستتمكن بقراءة البيانات الناتجة عن الحساسين السابقين من تحديد وجهة سنس هات وكيف تتحرك. مقياس حقل مغناطيسي Magnetometer، الذي يقيس شدة الحقل المغناطيسي، ويساهم أيضًا في تتبُّع حركة سنس هات بقياس شدة الحقل المغناطيسي الأرضي وتقدير جهة الشمال المغناطيسي، كما يُستخدم في الكشف عن الأجسام المعدنية والحقول الكهربائية. دُمجت الحساسات الثلاث السابقة ضمن رُقاقة واحدةٍ تحمل الاسم "‘ACCEL/GYRO/MAG" على لوحة سنس هات. حساس رطوبة، الذي يقيس كمية بخار الماء في الهواء وهذا ما يُعرف بالرطوبة النسبية relative humidity، التي تبدأ بالقيمة 0% (لا رطوبة في الهواء) وصولًا إلى 100% (الهواء مشبعٌ تمامًا ببخار الماء). يمكن استخدام بيانات الحساس لتوقع هطول الأمطار مثلًا. حساس ضغط بارومتري Barometric، الذي يقيس الضغط الجوي. وعلى الرغم من اعتقاد الكثيرين بارتباطه فقط بنشرات الطقس إلا أن له استخدامٌ آخر غير معروف، إذ يمكنه تعقبك إن كنت صاعدًا إلى تلة أو جبل أو نازلًا عنه نظرًا لتغيُّر الضغط الجوي للأرض عند الارتفاع أو الانخفاض عن مستوى سطح البحر. حساس درجة الحرارة لقياس درجة حرارة الوسط المحيط، وقد يتأثر بحرارة لوحة سنس هات، وبالتالي قد تحصل على حرارة أدنى أو أعلى من القراءة الصحيحة إذا كنت تضع باي ضمن حاضنة. لا يوجد حساس حرارة مستقل في سنس هات بل تستخدم حساسا الحرارة المدمجان مع حساسي الرطوبة والضغط، ويمكن لبرنامجك استخدام حساس أو حساسين فقط من هذه المجموعة. تثبيت سنس هات إذا اشتريت لوحة سنس هات، فابدأ بإخراجها من علبتها وتأكد من وجود جميع الأجزاء، وهي اللوحة نفسها وأربعة دعائم معدنية أو بلاستيكية تُعرف باسم المباعدات Spacers وثمانية براغي Screws. قد تجد أيضًا بعض الأرجل المعدنية المشابهة لأرجل GPIO على باي مثبتة على شريط بلاستيكي أسود، ادفع الشريط أسفل لوحة سنس هات في هذه الحالة والأرجل متجهة للأعلى حتى تسمع صوت إطباق. صُممت المباعدات لحماية سنس هات من الانحناء عند استخدام مقبض الألعاب، ورغم أن سنس هات ستعمل دون تثبيت المباعدات، إلّا أنّ استخدامها سيحمي لوحة سنس هات ولوحة راسبيري باي والمنصة GPIO من الضرر. ثبِّت المباعدات بدفع أربعة براغي من أسفل لوحة راسبيري باي إلى الأعلى عبر الثقوب الأربعة في كل زاوية، ثم لُف المباعدات فوق البراغي. ادفع سنس هات بعد التأكد من تطابق موقعها فوق منصة GPIO تمامًا نحو المنصة وحاول أن تجعلها مستويةً قدر الإمكان. ثبِّت سنس هات بواسطة البراغي الأربعة الباقية بإدخالها ضمن الثقوب الموجودة على زوايا سنس هات لتدخل ضمن المباعدات التي ثبتّها مسبقًا. ينبغي أن تكون سنس هات مستويةً تمامًا إن ثبّتها جيدًا ولن تنحني عندما تضغط على أزرار مقبض الألعاب. أعِد وصل باي إلى التغذية الكهربائية وسترى مصفوفة الأضواء على سنس هات وقد أضاءت بنمط ألوان قوس قزح ثم انطفأت. (شكل 1- ظهور نمط شكل قوس قزح عند وصل التغذية الكهربائية) فك البراغي العلوية الأربعة إذا أردت إزالة سنس هات، ثم ارفعها بحذر كي لا تثني أرجل GPIO كونها مرتبطةٌ بإحكام معها (قد تضطر إلى زحزحتها قليلًا بالمفك). أزِل المباعدات عن باي بعد ذلك لتتحرر البراغي السفلية الأربعة. مرحبا سنس هات سنبدأ مثل معظم المشاريع البرمجية بعرض رسالة ترحيب بمستخدمي سنس هات من خلال المصفوفة الضوئية، فإذا كنت ستستخدم مقلّد سنس هات، فعليك تشغيله بالنقر على أيقونة راسبيان والانتقال إلى فئة "برمجة Programming" ثم النقر على مقلّد سنس هات "Sense HAT Emulator". سكراتش ترحب بك شغّل سكراتش 2 من قائمة راسبيان ثم انقر على الفئة "كتل إضافية More Blocks" ضمن لوحة الكتل البرمجية، ثم انقر على زر "إضافة موسّع Add an Extension". اختر الموسّع "Pi SenseHAT"، ثم انقر "OK". ستظهر لك الآن جميع الكتل البرمجية التي تساعدك على التحكم بمختلف ميزات سنس هات بما في ذلك المصفوفة الضوئية وستجد هذه الكتل ضمن الفئة "كتل إضافية More Blocks". شكل 2-7 إضافة الموّسع "Pi SenseHAT" إلى سكراتش 2 اسحب الكتلة إلى منطقة بناء البرنامج، ثم ضع الكتلة تحتها مباشرةً وعدِّل النص، لتقرأ الكتلة عبارة "!Hello World" مع قيمة دوران مساوية 0 وبلونٍ أبيض وخلفية مُطفأة off. هناك طبعًا العديد من النقاط الواجب شرحها في الكتلة السابقة، لكننا سنكتفي الآن بالنقر على الراية الخضراء لتشغيل البرنامج ومراقبة سنس هات أو المقلّد. ستمر أحرف العبارة "!Hello, World" التي تكوّنها الأضواء البيضاء للمصفوفة تباعًا وببطء، كما هو موضح في الشكل التالي. تهانينا، نجح برنامجك في العمل. شكل 3-7 ستتحرك رسالتك خلال مصفوفة المؤشرات الضوئية بعد أن نجحت في عرض الرسالة لا بدّ من إلقاء نظرة على بقية خصائص الكتلة ، فبالإضافة إلى إمكانية تغيير الرسالة، يمكنك تغيير القيمة rotation التي تتحكم بطريقة عرض الرسالة على سنس هات. انقر على السهم الصغير بجوار rotation وغيِّر القيمة إلى 90 لتصبح الكتلة بالصيغة "Hello, World! at rotation 90 in colour white background off". شغِّل البرنامج وستلاحظ أنّ الرسالة ستتحرك من الأسفل إلى الأعلى وليس من اليسار إلى اليمين. شكل 4-7 ستتحرك الرسالة عموديًا الآن أعِد قيمة rotation إلى 0 وغيِّر لون الأضواء التي تعرض الرسالة بالنقر على السهم الصغير بجوار "in colour white"، ثم اختر لونًا من القائمة: أحمر red، أزرق blue، أصفر yellow، سماوي cyan، أرجواني magenta، أبيض white، إضافةً لخيار off لإطفاء الأضواء بدلًا من تشغيلها، وهو مكافئ للون الأسود. اختر حاليًا اللون الأصفر وانقر الراية الخضراء ولاحظ تغيّر لون النص. شكل 5-7 تغيير لون الرسالة المعروضة انقر أخيرًا على السهم الصغير بجوار الخيار background لترى قائمة الألوان السابقة نفسها. لن يتغير لون المؤشرات الضوئية التي تعرض الرسالة هذه المرة بل ألوان مجموعة المؤشرات التي لا تعرضها والتي تُسمى خلفية Background. غيِّر ألوان النص والخلفية لتصل إلى التشكيلة المثالية، فلن تتماشى بعض الألوان مع البعض الآخر. وطالما أنك قادر على تحريك رسالتك عبر الشاشة، يمكنك مشاهدة الحروف كلٌ على حدى. اسحب الكتلة خارج منطقة بناء البرنامج لحذفها واستبدلها بالكتلة ثم انقر الراية الخضراء وسترى الفرق. تعرض المصفوفة حرفًا واحدًا كل مرة في المكان نفسه حتى نغيّر ذلك دون أن تتحرك الحروف عبر المصفوفة أو تختفي. يُطبَّق على هذه الكتلة نفس النظام اللوني المطبَّق على الكتلة السابقة، لذلك حاول تغيير لون الحرف إلى الأحمر. شكل 6-7 يظهر على الشاشة حرف واحد بايثون ترحب بك حمّل أيًا من نمطي بيئة العمل ثوني Thonny البسيط، أو القياسي بالنقر على أيقونة راسبيان، ثم انتقل إلى فئة "برمجة Programming"، ثم انقر أخيرًا على أي من اختصاري ثوني. ستغطي واجهة ثوني واجهة المقلّد إذا كنت تستخدمه، لذلك غيِّر موقع النافذتين حتى تتمكن من عرضهما معًا على الشاشة. ستحتاج إلى إدراج مكتبة SenseHat، إذا كنت ستستخدم بايثون لكتابة برنامجك سواءٌ لتجهيزة سنس هات، أم للمقلّد. اكتب ما يلي في نافذة الشيفرة: from sense_hat import SenseHat sense = SenseHat() للمكتبة دالةٌ بسيطة تقرأ الرسالة وتنسِّقها لتظهر على مصفوفة الأضواء ومن ثم تحرِّكها بلطف. اكتب الشيفرة التالية الآن: sense.show_message("Hello, World!") احفظ برنامجك باسم "Hello Sense HAT"، ثم انقر أيقونة التشغيل "Run"، ستتحرك الرسالة ببطء على شاشة المصفوفة الضوئية. تهانينا، نجح برنامجك في العمل. from sense_hat import SenseHat إلى: from sense_emu import SenseHat وبالعكس. شكل 7-7 تحريك الرسالة عبر شاشة المصفوفة الضوئية. يوجد للدالة ()show_message ميزاتٌ أخرى، لذلك عُد إلى برنامجك وعدّل الدالة لتصبح على النحو التالي: sense.show_message("Hello, World!", text_colour=(255, 255, 0), back_colour=(0, 0, 255), scroll_speed=(0.05)) تُعرف هذه التعليمات التي تفصل بينها فاصلة "," داخل قوسي الدالة باسم المعاملات Parameters، وهي تتحكم بعمل الدالة من نواحٍ عدة، ويُعد ()=scroll_speed أبسط هذه المعاملات، إذ يتحكم بسرعة عرض الرسالة على الشاشة؛ فلو كانت قيمته 0.05، فستتحرك الرسالة بسرعة مضاعفة عن السرعة الاعتيادية، وكلما زادت القيمة كلما قلت السرعة. أما المعاملان ()=text_colour و ()=back_colour (مكتوبان وفق التهجئة البريطانية على خلاف تعليمات بايثون الأخرى) فيحددان لون النص ولون الخلفية، لكنهما لا يستخدمان أسماء الألوان بل يستخدمان النظام اللوني الثلاثي الذي تحدد فيه نسب الألوان الأساسية الأحمر ثم الأخضر ثم الأزرق واختصارًا RGB، إذ يمثل الرقم الأول من الثلاثية كمية اللون الأحمر في اللون المحدد والتي تأخذ القيم من 0 (لا لون أحمر) حتى 255 (الحد الأقصى للون الأحمر)، ويمثل الرقم الثاني كمية اللون الأخضر، والثالث كمية اللون الأزرق. انقر على أيقونة التشغيل "Run" وراقب سنس هات. لاحظ كيف تتحرك الرسالة التي تظهر بلون أصفر على خلفية زرقاء بسرعة أكبر. بدِّل قيم المعاملات السابقة لتحصل على طريقة العرض الملائمة. شكل 8-7 تغيير لون النص والخلفية. يمكنك استخدام المتغيرات لإعطاء أسماء مناسبة للون الذي تريده بدلًا من استخدام نظام RGB. لتجربة ذلك اكتب الشيفرة التالية قبل سطر الدالة ()sense.show_message: yellow = (255, 255, 0) blue = (0, 0, 255) ثم عدًل سطر الدالة نفسها ليصبح على النحو التالي: sense.show_message("Hello, World!", text_colour=(yellow), back_ colour=(blue), scroll_speed=(0.05)) إذا نقرت على أيقونة التشغيل مجددًا فلن تلحظ أية تغيرات، وستبقى رسالتك بلون أصفر وخلفية زرقاء وكل ما هناك أنك استخدمت المتغيرات لجعل اللون الذي اخترته مقروءًا بدلًا من استخدام مجموعة أرقام؛ وهكذا يمكن تعريف العدد الذي تشاء من الألوان ومنحها أسماءً، فيمكنك مثلًا تسمية اللون (255,0,0) باسم "أحمر red" واللون (255,255,255) باسم "أبيض white" وسيكون "الأسود black" هو حتمًا اللون (0,0,0). يمكنك كذلك عرض الرسالة مثل حروف متلاحقة واحدًا تلو الآخر بدل تحريكها، ولتنفيذ ذلك احذف سطر التعليمة: sense.show_message() واستبدله بالشيفرة التالية: sense.show_letter("Z") انقر على أيقونة التشغيل لترى الحرف "Z" على شاشة سنس هات، إذ سيبقى الحرف مكانه هذه المرة، فلا تتحرك الحروف المفردة بحد ذاتها على الشاشة. يمكنك كذلك التحكم في لون وخلفية الحرف من خلال الدالة ()sense.show_letter وباستخدام معاملات مشابهةٍ لمعاملات الدالة ()sense.show_message، جرّب ذلك. شكل 9-7 إظهار حرف وحيد الرسم بالأضواء لا تُستخدم المصفوفة الضوئية في سنس هات لعرض الرسائل فقط، بل يمكنك عرض الصور أيضًا، إذ يُعامل كل مؤشر ضوئي في المصفوفة مثل بكسل pixel (بكسل= عنصر-صورة أو بكسل كما هو شائع) مفرد في الصورة التي تختارها، وبالتالي ستكون قادرًا على إحياء برامجك بالصور وحتى الرسوم المتحركة. ولكي تتمكن من إظهار الرسوميات والصور، لا بدّ أن تكون قادرًا على تغيير كل مؤشر ضوئي على حدى، لذلك علينا أولًا فهم طريقة تنظيم المؤشرات الضوئية في مصفوفة سنس هات لكتابة البرنامج الصحيح الذي يضيء ويطفئ المؤشر الضوئي المطلوب. شكل 10-7 نظام الإحداثيات الخاص بالمصفوفة الضوئية. تضم المصفوفة ثمانية مؤشرات ضوئية في كل صف وثمانية في كل عمود، وتُعَد المؤشرات كما هو الحال في معظم لغات البرمجة إذ تبدأ من 0 وتنتهي عند الرقم 7، وسيكون المؤشر الضوئي في الزاوية اليسارية العليا في الصف 0 والعمود 0 أي إحداثياته (0,0)، إذ يمثِّل الإحداثي الأول قيمة X التي تشير إلى الأعمدة والإحداثي الثاني قيمة Y التي تشير إلى الأسطر. وستكون إحداثيات المؤشر في الزاوية اليمينية السفلية بناء على هذه المنظومة (7,7) وهكذا. يمكنك ملاحظة المؤشر الضوئي الأزرق مثلًا المبين في الشكل السابق عند الإحداثيات (0,2) والأحمر عند الإحداثيات (4,7). قد يفيدك رسم مخطط للمؤشرات الضوئية على ورقة مقسمة عندما تخطط لعرض صورة ما على شاشة سنس هات، كما يمكنك الاستعانة بالجداول الإلكترونية spreadsheets لتخطيط طريقة عرض الصورة مثل برنامج ليبر أوفيس كالك LibreOffice Calc. عرض الصور باستخدام سكراتش ابدأ مشروعًا جديدًا في سكراتش بعد حفظ مشروعك السابق إن أردت. حمّل الموسِّع "PI Sense HAT" من خلال الفئة "كتل إضافية More Blocks"، ولا تنس أن تعيد هذه الخطوة في كل مرة تنشئ فيها مشروعًا جديدًا يستخدم سنس هات وإلا لن تظهر الكتل التي تتحكم بهذه التجهيزة. اسحب الكتلة إلى منطقة بناء البرنامج، ثم ضع تحتها مباشرةً الكتلة . انقر على الراية الخضراء دون أن تنظر مباشرةً إلى المصفوفة الضوئية لأن المؤشرات ستضيء بلون أبيض لامع قد لا يكون النظر إليها مباشرة أمرًا مريحًا. شكل 11-7 لا تنظر مباشرةً إلى مصفوفة الأضواء عندما تضيء بلون أبيض لامع انقر على السهم الصغير بجوار الخيار white واختر لونًا مختلفًا، ثم أعد تشغيل البرنامج. اختر من جديد الخيار off بدلًا من اختيار لون محدد، ثم شغِّل البرنامج مجددًا لتُطفأ كل الأضواء في هذه الحالة. يمكنك استخدام نظام RGB لمزج اللون المطلوب إذا أردت لونًا خاصًا بك. لهذا اسحب الكتلة خارج منطقة بناء البرنامج واستبدلها بالكتلة انقر على الراية الخضراء وستضيء المؤشرات بلون أبيض لامع من جديد. يمكنك الآن تصميم اللون الذي تريد بتحديد كميات اللون الأحمر والأخضر والأزرق في الكتلة السابقة بعد الخيارات R و G و B على التوالي. يمكن أن تحمل أي كمية قيمًا من 0 حتى 255. عدّل الكتلة لتصبح ثم انقر الراية الخضراء لتضيء المصفوفة الآن بلون أخضر لامع. شكل 12-7 ستضيء المصفوفة كلها باللون الأخضر اللامع. جرب قيمًا مختلفة لمنظومة RGB لتحصل على اللون الذي تريده وسجل هذه القيم لاستخداماتك المستقبلية. ولكي تتمكن من عرض صورةٍ ما، لا بدّ أن تكون قادرًا على التحكم بكل مؤشر ضوئي على حدى. لتنشئ مثلًا نسختك عن البرنامج الذي يعرضه الشكل 10-7، الذي يُضاء فيه مؤشرين ضوئيين لبيكسلين باللون الأحمر والأزرق، غيِّر الكتلة إلى ، ثم اسحب كتلتي لتكونا تحتها مباشرةً وغير قيمهما لتكونا كما في الشكل التالي: انقر على الراية الخضراء لتشاهد الضوئين الأحمر والأزرق كما في الشكل 10-7. تهانينا، تستطيع الآن التحكم بكل مؤشر ضوئي على نحوٍ مستقل. عدّل الكتل السابقة كما في التسلسل التالي وأضف الكتل المناسبة لتحصل على البرنامج التالي: حاول أن تتوقع الصورة التي ستظهر على المصفوفة الضوئية بناءً على الإحداثيات التي استخدمتها في كتل التسلسل السابق قبل أن تنقر على الراية الخضراء، ثم شغّل البرنامج لترى إن كنت على حق. على الرغم من إمكانية استخدام كتل في عرض الصور البسيطة، لكن موسِّع سنس هات الموجود في النسخة سكراتش 2 لن يكون مناسبًا لعرض صور معقدة أو رسوميات متحركة. لذلك فكِّر في الانتقال إلى بايثون عند كتابة برنامجك. عرض الصور باستخدام بايثون ابدأ برنامجًا جديدًا في ثوني واحفظه باسم "Sense HAT Drawing" ثم اكتب الشيفرة التالية في نافذة الشيفرة وانتبه إلى استبدال sense_hat بمقابلتها sense_emu إذا كنت ستستخدم المقلّد: from sense_hat import SenseHat sense = SenseHat() وتذكر أنك ستحتاج كلا سطري الشيفرة السابقين لاستخدام سنس هات. أضف بعد ذلك السطر التالي: sense.clear(255, 255, 255) انقر على أيقونة التشغيل Run دون النظر مباشرةً إلى المصفوفة الضوئية لأنها ستضيء بأكملها باللون الأبيض اللامع عند تشغيل البرنامج. شكل 13-7 لا تنظر مباشرة إلى مصفوفة الأضواء عندما تضيء بلون أبيض لامع صُممت الدالة ()sense.clear لإلغاء برمجة كل المؤشرات الضوئية لكنها تقبل أيضًا معاملات لونية وفق نظام RGB، أي يمكنك تغيير لون المصفوفة إلى أي لون تريد. عدّل الشيفرة في السطر الأخير على النحو التالي: sense.clear(0, 255, 0) انقر على أيقونة التشغيل Run وسيتحول لون سنس هات إلى الأخضر اللامع. جرِّب ألوانًا مختلفة أو استخدم المتغيرات التي سمّيتها سابقًا بأسماء الألوان في برنامجك "Hello World" لتبسيط الأمر أكثر. شكل 14-7 ستضيء المصفوفة الضوئية باللون الأخضر اللامع. لإطفاء الأضواء، استخدم قيمة RGB الموافقة للون الأسود وهي (0,0,0)، كما يمكنك تنفيذ ذلك بطريقة أسهل وذلك بتعديل السطر الأخير من برنامجك ليصبح على النحو التالي: sense.clear() ستطفئ الدالة ()sense.clear أضواء سنس هات إن كانت أقواسها فارغة، وهذا ما ستحتاجه لإلغاء برمجة المؤشرات الضوئية بأكملها. شكل 15-7 استخدم الدالة sense.clear لإطفاء أضواء مصفوفة سنس هات. لتنشئ نسختك عن البرنامج الذي يعرضه الشكل 10-7 والمكوّن من مؤشرين ضوئيين محددين يضيئان باللونين الأحمر والأزرق، أضِف الشيفرة التالية مباشرةً بعد الدالة ()sense.clear: sense.set_pixel(0, 2, (0, 0, 255)) sense.set_pixel(7, 4, (255, 0, 0)) يمثِّل المعامل الأول من الدالة ()sense.set_pixel الإحداثي X (رقم العمود) لمنظومة إحداثيات المصفوفة، ويمثِّل المعامل الثاني الإحداثي Y، بينما يحدد الإحداثي الثالث لون المؤشر الضوئي بطريقة RGB. انقر على أيقونة التشغيل Run لترى تنفيذ الشيفرة، ولاحظ كيف ستضيء المصفوفة على نحوٍ مشابه لما يعرضه الشكل 10-7. احذف الآن السطرين السابقين واكتب الشيفرة التالية: sense.set_pixel(2, 2, (0, 0, 255)) sense.set_pixel(4, 2, (0, 0, 255)) sense.set_pixel(3, 4, (100, 0, 0)) sense.set_pixel(1, 5, (255, 0, 0)) sense.set_pixel(2, 6, (255, 0, 0)) sense.set_pixel(3, 6, (255, 0, 0)) sense.set_pixel(4, 6, (255, 0, 0)) sense.set_pixel(5, 5, (255, 0, 0)) تأمل إحداثيات المؤشرات الضوئية في الشيفرة السابقة وتوقع نتيجتها قبل تشغيل البرنامج، ثم تحقق من ذلك بعد التشغيل. وكما ترى سيكون رسم أي لوحة بتكرار استدعاء واحد للدالة ()sense.set_pixel بطيئًا، ومن الأفضل تغيير عدة بكسلات في الوقت نفسه. لهذا احذف كل الأسطر التي تستدعي الدالة ()sense.set_pixel واكتب الشيفرة التالية: g = (0, 255, 0) b = (0, 0, 0) creeper_pixels = [ g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, b, b, g, g, b, b, g, g, b, b, g, g, b, b, g, g, g, g, b, b, g, g, g, g, g, b, b, b, b, g, g, g, g, b, b, b, b, g, g, g, g, b, g, g, b, g, g ] sense.set_pixels(creeper_pixels) سنشرح الشيفرة السابقة لاحقًا لكن ابدأ بتشغيل البرنامج لنرى إن استطعت تمييز الشكل الذي ستعرضه سنس هات. لاحظ كيف يُنشئ أول سطرين متغيرين نسند إليهما قيم RGB المحددة للونين الأخضر g والأسود b لتسهيل كتابة وقراءة الشيفرة؛ وتنشئ كتلة الشيفرة التي تليهما متغيرًا يضم بين قوسين مربعين ألوان جميع بكسلات الشاشة الضوئية تفصل بينها الفاصلة ",". لاحظ كيف استخدمنا المتغيرين السابقين g و b بدلًا من الأرقام في تحديد الألوان وسيظهر حلزون نتيجة تنفيذ الشيفرة كما في الشكل 16-7. تقبل الدالة (sense.set_pixels(creeper_pixels المتغير creeper_pixels مثل معامل، ثم ترسم المصفوفة كاملةً في اللحظة نفسها، وهذا أسهل طبعًا من رسم كل بكسل لوحده. شكل 16-7 عرض صورة على المصفوفة الضوئية. من الممكن أيضًا تدوير أو قلب الصورة لعرض الصورة بالشكل الصحيح عند تدوير سنس هات، أو لتصميم رسم متحرك بسيط انطلاقًا من صورة غير متناظرة. ابدأ بتعديل قيم المتغير creeper_pixels لنغمض عين الحلزون على النحو التالي: creeper_pixels = [ g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, b, b, g, g, g, g, g, g, b, b, g, g, g, g, b, b, g, g, g, g, g, b, b, b, b, g, g, g, g, b, b, b, b, g, g, g, g, b, g, g, b, g, g ] انقر على Run وسترى عين الحلزون وقد أغمضت كما هو موضح في الشكل التالي. ولإنشاء رسمٍ متحرك انتقل إلى بداية برنامجك وأضِف السطر التالي: from time import sleep عُد إلى آخر البرنامج وأضف ما يلي: while True: sleep(1) sense.flip_h() انقر على زر التشغيل Run وسترى الحلزون وهو يغلق ويفتح عينيه بالتناوب. شكل 17-7 رسم متحرك من إطارين تقلب الدالة ()flip_h الصورة وفق محورها الأفقي، بينما تقلبها الدالة ()flip_v وفق محورها العمودي؛ وتستطيع أيضًا تدوير الصورة بزوايا 0 و 90 و 180 و 270 ثم العودة إلى 0 درجة باستخدام الدالة (sense.set_rotation(90 بعد استبدال 90 بالزاوية المطلوبة. حاول أن تستخدم هذه الدالة ليدور الحلزون بدلًا من إغماض عينيه> تحسس العالم من حولك من الممتع العمل مع المصفوفة الضوئية لسنس هات، لكن تظهر قوتها الحقيقية عند استخدام حساساتها المختلفة، إذ تتيح لك تلك الحساسات استشعار المحيط من درجة الحرارة إلى الحركة ومن ثم استخدام هذه المعلومات في برامجك بالطريقة التي تريد. تحسس البيئة المحيطة تأخذ حساسات الضغط والحرارة والرطوبة لسنس هات البيانات من البيئة المحيطة بها، لذلك فهي حساسات بيئية. استشعار البيئة المحيطة باستخدام سكراتش ابدأ برنامجًا جديدًا في سكراتش بعد حفظ البرنامج السابق إن أردت، ثم أضف الموّسع "Sense HAT" إلى فئة "كتل إضافية More Blocks". اسحب الكتلة إلى منطقة بناء البرنامج، وضع تحتها الكتلة . من المفيد تنفيذ هاتين الخطوتين في بداية برنامجك لتتأكد من عدم عرض أي شيء على المصفوفة الضوئية قد يكون عالقًا من برنامج سابق. اسحب بعد ذلك الكتلة الموجودة في الفئة "مظهر Look"، وضعها مباشرةً تحت الكتل السابقة. لقراءة الضغط الجوي، ابحث عن الكتلة في فئة "كتل إضافية More Blocks"، ثم اسحبها وأفلتها مكان الكلمة "!Hello" في الكتلة . انقر على الراية الخضراء، وستبلغك شخصية القط القراءة الحالية للضغط الجوي من حساس الضغط بالميلي بار، وستختفي الرسالة بعد ثانيتين. حاول أن تنفخ فوق سنس هات (أو تزيد قيمة الضغط عبر المحاكي) وأن تشغل البرنامج بالتوازي فسترى قراءة أعلى هذه المرة. شكل 18-7 عرض قراءة حساس الضغط ولكي نعرض مستوى الرطوبة بدلًا من الضغط، احذف الكتلة واستبدلها بالكتلة . شغِّل البرنامج الآن وسترى قيمة مستوى الرطوبة في الغرفة. جرّب كذلك أن تنفخ فوق سنس هات (أو تزيد قيمة الرطوبة عبر المحاكي) وأن تشغّل البرنامج بالتوازي فسترى قراءة أعلى هذه المرة لأن نفسك رطبٌ جدًا. شكل 19-7 عرض قراءة حساس الضغط إذا أردت الحصول على درجة الحرارة احذف الكتلة واستبدل بها الكتلة ، ثم شغِّل البرنامج مجددًا وستظهر درجة الحرارة بالدرجات المئوية (سلزيوس). قد لا تكون الدرجة المعروضة نفسها درجة حرارة الغرفة الفعلية، إذ تنتج راسبيري باي حرارةً أثناء عملها فتسخِّن سنس هات وحساساتها. شكل 20-7 عرض قراءة حساس الحرارة تحسس البيئة المحيطة باستخدام بايثون أنشئ برنامجًا جديدًا في ثوني واحفظه باسم "Sense HAT Sensors"، ثم اكتب الشيفرة التالية منتبهًا إلى استخدام المكتبة sense_emu بدلًا عن sense_hat عند استخدام المقلِّد: from sense_hat import SenseHat sense = SenseHat() sense.clear() من المفيد تنفيذ الأمر ()sense.clear في بداية برنامجك لتتأكد من عدم عرض أي شيء على المصفوفة الضوئية قد يكون عالقًا من برنامجٍ سابق. اكتب الأمر التالي لقراءة بيانات حساس الضغط: pressure = sense.get_pressure() print(pressure) انقر على أيقونة التشغيل Run وسترى قراءة الحساس مطبوعةً في نافذة المفسِّر بالميلي بار. حاول أن تنفخ فوق سنس هات، أو تزيد قيمة الضغط عبر المحاكي، وأن تشغِّل البرنامج بالتوازي فسترى قراءة أعلى هذه المرة. شكل 21-7 إظهار قراءة أعلى للضغط للانتقال إلى قراءة حساس الرطوبة، احذف السطرين السابقين ثم اكتب ما يلي: humidity = sense.get_humidity() print(humidity) انقر على أيقونة التشغيل Run، وسترى قراءةً أخرى في نافذة المفسّر تمثِّل الرطوبة النسبية بالنسبة المئوية. جرّب كذلك أن تنفخ فوق سنس هات (أو تزيد قيمة الرطوبة عبر المحاكي) وأن تشغل البرنامج بالتوازي فسترى قراءةً أعلى هذه المرة، فنفسك رطبٌ جدًا. شكل 22-7 إظهار قراءة حساس الرطوبة. ولتعرض قراءة حساس الحرارة، أزِل آخر سطرين واستبدلهما بالشيفرة التالية: temp = sense.get_temperature() print(temp) شغِّل البرنامج مجددًا وستظهر درجة الحرارة بالدرجات المئوية (سلزيوس). قد لا تكون الدرجة المعروضة نفسها درجة حرارة الغرفة الفعلية، إذ تنتج راسبيري باي حرارةً أثناء عملها فتسخن سنس هات وحساساتها. شكل 20-7 عرض قراءة حساس الحرارة تعطي سنس هات درجة الحرارة عادة بناءً على قراءة حساس الحرارة المدمج ضمن حساس الرطوبة، لكن إذا أردت قراءة الحساس الآخر المُدمج مع حساس الضغط استعمل الدالة ()sense.get_temperature_from_pressure، وقد تستخدم القراءتين معًا ثم تأخذ متوسطهما لدقة أفضل، لهذا احذف السطرين الأخيرين واكتب: htemp = sense.get_temperature() ptemp = sense.get_temperature_from_pressure() temp = (htemp + ptemp) / 2 print(temp) انقر على أيقونة التشغيل Run، وسترى قيمة درجة الحرارة المأخوذة مثل متوسطٍ لقراءتي الحساسين ضمن نافذة المفسِّر، وإذا كنت تستخدم المقلّد فستحصل على النتيجة نفسها في الحالات الثلاث. شكل 24-7 درجة الحرارة بناء على قراءتي كلا الحساسين استشعار الحركة يُشكّل الجيروسكوب وحساسا التسارع والحقل المغناطيسي ما يُسمى بوحدة قياس العطالة inertial measurement unit -أواختصارًا IMU-. وعلى الرغم من أنّ قراءة هذه الحساسات ستُؤخذ تقنيًا من البيئة المحيطة، مثل شدة الحقل المغناطيسي في الجوار، إلا أنها تُستخدم عادةً لاستشعار حركة سنس هات، إذ تظهر قيمة IMU مثل مجموعة قراءات لعدّة حساسات تسمح لك بعض لغات البرمجة بقراءة كل منها بصورةٍ مستقلة، بينما تعطيك بعضها الآخر قراءةً مشتركةً لكل الحساسات. ولكي تتعامل مع IMU، لا بدّ من فهم طبيعة حركة الأشياء. تتحرك سنس هات وباي المتصلة معها في فراغ ثلاثي الأبعاد يحدده معلم إحداثي ثلاثي المحاور كما يلي: المحور X وتُحدد عليه الحركة الجانبية من طرف إلى طرف. المحور Y وتُحدد عليه الحركة للأمام والخلف. المحور Z وتُحدد عليه الحركة للأعلى والأسفل. ويمكن لباي الدوران حول هذه المحاور، لكن وصف هذه الحركات سيتغير قليلًا؛ إذ يُدعى الدوران حول المحور X "تدحرج roll" وحول المحور Y "تقلّب pitch" وحول المحور Z "فتل Yaw". فعندما تدوّر سنس هات حول محورها القصير "Y" فأنت تُقلّبها، وعندما تدور حول المحور الطولي "X" تدحرجها، وتفتلها عندما تدور بوضعها الأفقي على الطاولة. فكّر بالأمر مثل طائرة، إذ تتقلَّب الطائرة بحلقة دائرية وهي تقلع حتى تصل إلى الارتفاع المطلوب وتتدحرج عندما تدور دوران النصر، وتفتل عندما تريد الدوران لتغيير الاتجاه. شكل 25-7 المحاور الفراغية لتحديد قيمة MUI لسنس هات استشعار الحركة باستخدام سكراتش ابدأ برنامجًا جديدًا وحمّل موسِّع سنس هات، ثم اسحب الكتلة إلى منطقة بناء البرنامج، وضع تحتها الكتلة ، ثم غيّرها بالنقر على الزر الصغير بجوار الكلمة "white" إلى . اسحب الكتلة إلى أسفل التسلسل السابق وضع داخلها الكتلة . ستحتاج إلى كتل ضم join blocks لإظهار قراءات المحاور الثلاث (تدحرج- تقلب- فتل)، إضافةً إلى كتل سنس هات الموافقة. تذكر إضافة فواصل ومسافات فارغة أثناء ترتيب كتل الضم لتسهيل قراءة النتيجة. انقر على الراية الخضراء لتشغيل البرنامج، ثم حاول تدوير سنس هات وباي بحذر كي لا تزيح الكابلات. ستظهر قيم المحاور الثلاث وتتغير باستمرار مع تغير وضع سنس هات. شكل 26-7 عرض قيم التقلب pitch والتدحرج roll والفتل yaw استشعار الحركة باستخدام بايثون ابدأ برنامجًا جديدًا في ثوني واحفظه باسم "Sense HAT Movement"، ثم اكتب الشيفرة التالية منتبهًا إلى استخدام المكتبة sense_emu بدلًا عن sense_hat عند استخدام المقلد: from sense_hat import SenseHat sense = SenseHat() sense.clear() لاستخدام معلومات عن IMU في تحديد الوجهة الحالية لسنس هات وفقًا لمحاورها الثلاث، اكتب الشيفرة التالية: orientation = sense.get_orientation() pitch = orientation["pitch"] roll = orientation["roll"] yaw = orientation["yaw"] print("pitch {0} roll {1} yaw {2}".format(pitch, roll, yaw)) انقر على أيقونة التشغيل Run وسترى قراءات اتجاه سنس هات على المحاور الثلاث. حاول تدوير سنس هات ثم انقر على أيقونة التشغيل مجددًا وستلاحظ تغيُّر القراءات بما يعكس الوجهة الجديدة. عرض قيم التقلب pitch والتدحرج roll والفتل yaw يمكن أن يسهم قياس MUI بأكثر من تحديد وجهة سنس هات فهو قادرٌ على اكتشاف الحركة. وللحصول على قراءة دقيقة للحركة، لا بدّ من قراءة MUI باستمرار من خلال حلقات، فلن تعطيك قراءة واحدة أية فائدة تُذكر في استشعار الحركة على خلاف تحديد الوجهة. احذف كل ما يأتي بعد الدالة ()sense.clear واكتب التالي: while True: acceleration = sense.get_accelerometer_raw() x = acceleration['x'] y = acceleration['y'] z = acceleration['z'] لدينا الآن ثلاثة متغيرات لتخزين قراءات مقياس التسارع على المحاور الثلاث: X للحركة يمينًا ويسارًا، Y للحركة أمامًا وخلفًا، Z للأعلى والأسفل. من الصعب أحيانًا قراءة بيانات مقياس التسارع، لذلك اكتب الشيفرة التالية لتدوير الرقم إلى أقرب عدد صحيح وبذلك يسهل فهمها: x = round(x) y = round(y) z = round(z) اطبع النتائج بعد ذلك كما يلي: print("x={0}, y={1}, z={2}".format(x, y, z)) انقر على أيقونة التشغيل وسترى قراءات مقياس التسارع مطبوعةً على شاشة المفسِّر، لكنه سيستمر في طباعة الأرقام بلا توقُّف وعليك النقر على أيقونة "Stop" لإيقاف البرنامج. شكل 28-7 قراءات مقياس التسارع مقرّبة إلى أقرب رقم صحيح. نلاحظ أن مقياس التسارع يعطي القراءة 1.0 للجاذبية (1G) على أحد المحاور (المحور Z إذا كانت باي وسنس هات أفقيتان على الطاولة) على الرغم من أن سنس هات لا تتحرك، والسبب وراء ذلك هو أن الحساس يستشعر الجاذبية الأرضية التي تشد سنس هات نحو مركز الأرض. حاول رفع سنس هات مع باي للأعلى بحذر أثناء عمل البرنامج، لكن انتبه كي لا تُزاح الكابلات. أمِل اللوحتان بحيث يتجّه منفذا الشبكة المحلية والناقل USB نحو الأرض فستتغير القراءة لتصبح 0G على Z و 1G على X، وستتحول القراءتان على X و Z إلى 0G وعلى Y إلى 1G عندما تميل اللوحتان بحيث يتجه منفذ HDMI لباي نحو الأرض. إذا حاولت أن تميلها بحيث يتجه منفذ HDMI نحو السقف ستتغير القراءة على Y لتصبح 1G-. وبمعرفة أن الجاذبية الأرضية هي تقريبًا 1G وفهم المحاور الفراغية بالطريقة التي عرّفناها سابقًا، ستتمكن من استعمال قراءات مقياس التسارع لتحديد توجّه اللوحة نحو الأسفل والأعلى، وستتمكن أيضًا من اكتشاف الحركة. حاول أن تهزّ اللوحتين وراقب الأرقام في نافذة المفسِّر، وكلّما زادت شدة الاهتزاز كلما زادت قراءة مقياس التسارع. عندما تستخدم الدالة ()sense.get_accelerometer_raw، فأنت تخبر سنس هات في هذه الحالة أن تعطِّل الحساسين الباقيين في IMU (الجيروسكوب ومقياس الحقل المغناطيسي) وتعيد قراءات مقياس التسارع فقط، ويمكن طبعًا فعل نفس الشيء عند استخدام أي حساسٍ آخر. استبدل السطر: acceleration = sense.get_accelerometer_raw() بالسطر: orientation = sense.get_gyroscope_raw() غيّر الكلمة acceleration في الأسطر الثلاثة داخل الحلقة إلى orientation، ثم انقر أيقونة التشغيل لترى قيم توجه سنس هات على المحاور الثلاث مدوّرةً إلى أقرب عدد صحيح. ستأتيك البيانات هذه المرة من الجيروسكوب فقط دون استخدام مقياسي الحقل المغناطيس والتسارع، ويفيد ذلك في تحديد وجهة سنس هات إن تحركت على ظهر روبوت مثلًا دون الحاجة لأخذ تعقيدات الحركة بالحسبان أو استخدامها في جوار مصدر قوي للإشعاع المغناطيسي. لاستخدام مقياس الحقل المغناطيسي، أوقف البرنامج ثم احذف كل أسطر برنامجك ما عدا الأربعة الأولى منه، ثم اكتب الشيفرة التالية تحت بداية الحلقة while True: north = sense.get_compass() print(north) شغِّل برنامجك وسترى اتجاه الشمال المغناطيسي وقد طُبع في نافذة المفسِّر. دوّر سنس هات بلطف وستلاحظ تغيرات القراءة نظرًا لانحراف توجهها بالنسبة للشمال المغناطيسي. لقد نجحت في صناعة بوصلة. قرِّب مغناطيسًا (يمكنك استخدام المغانط التي تُلصق على البرادات) من سنس هات وراقب تغيّر قراءة مقياس الحقل المغناطيسي. التحكم بمقبض الألعاب يتواجد في الزاوية اليمينية السفلية لسنس هات، وقد تراه صغيرًا لكنه فعّال جدًا وقادرٌ على تمييز إشارات الدخل من أربعة جهات (أمام وخلف ويمين ويسار)، كما يمتلك قناة دخل خامسة تصل إليها بالضغط على المقبض في منتصفه وكأنه زر الكبس في المنتصف. تحذير: لا ينبغي استخدام مقبض سنس هات ما لم تستخدم المباعدات التي تحدثنا عن تثبيتها سابقًا، لأن الضغط على المقبض سيثني سنس هات مما يسبب في تضررها وتضرر منصة GPIO معها. التحكم بمقبض الألعاب باستخدام سكراتش ابدأ برنامجًا جديدًا وحمّل موسِّع سنس هات، ثم اسحب الكتلة إلى منطقة بناء البرنامج وضع تحتها الكتلة واضبط الخيار "white" على "off". يرتبط مقبض سنس هات في سكراتش scratch مع مفاتيح الأسهم في لوحة المفاتيح، فعندما تضغط زر "أمام" في المقبض فهذا أمرٌ مماثل لضغط مفتاح السهم "أعلى" وكذلك الأمر عند ضغط زر المقبض اليساري فهذا مماثلٌ لضغط مفتاح السهم اليساري في لوحة المفاتيح وهكذا، بينما يطابق ضغط المقبض في منتصفه مثل زر الكبس ضغط المفتاح "Enter" في لوحة المفاتيح. تحذير: لا يتوفر مقبض الألعاب سوى على سنس هات الفيزيائية، فإذا كنت تستخدم المقلِّد فعليك بمفاتيح الأسهم على لوحة المفاتيح لمحاكاة المقبض. نظرًا للارتباط السابق، سنستعمل كتل الأحداث نفسها التي نستخدمها لقراءة مُدخلات لوحة المفاتيح. اسحب الآن الكتلة إلى منطقة بناء البرنامج، ثم غيّر الخيار فيها إلى "up arrow" بدلًا من "space". اسحب الكتلة وضعها تحت الكتلة السابقة حتى نرى نتيجة هذا البرنامج. تحرك إلى الأمام من خلال المقبض وستشاهد القط يحييك بالعبارة "!Hello". عدّل العبارة السابقة لتصبح "!Joystick Up" ثم أضف كتل أحداث Events وكتل مظهر Looks إلى برنامجك حتى يعطي الضغط على أي زر من أزرار المقبض الخمسة نتيجة على النحو التالي: اضغط على أزرار المقبض بكل الاتجاهات لكي ترى نتيجة عملك. التحكم بمقبض الألعاب باستخدام بايثون ابدأ برنامجًا جديدًا في ثوني واحفظه باسم "Sense HAT Joystick"، ثم اكتب الأسطر الثلاث التي تهيئ سينس هات وتطفئ أضواء المصفوفة: from sense_hat import SenseHat sense = SenseHat() sense.clear() استخدم تاليًا حلقةً لا نهائية while True وأخبر بايثون أن ينصت ضمنها إلى أحداث الدخل الناتجة عن الضغط على أزرار المقبض. سيزيح ثوني الشيفرة تلقائيًا بمسافة بادئة داخل الحلقة: while True: for event in sense.stick.get_events(): أضِف أخيرًا الشيفرة التي تنفذ شيئًا عند ضغط زر المقبض المحدد داخل حلقة for، وسيزيحها ثوني تلقائيًا أيضًا بمسافة بادئة: print(event.direction, event.action) انقر على أيقونة التشغيل Run، واضغط على الأزرار المختلفة لمقبض سنس هات وسترى أسماء الجهات التي تحركت نحوها قد طُبعت في نافذة المفسِّر. وستلاحظ أيضًا أن هناك حدثان مرتبطان بكبسةٍ واحدةٍ على أحد أزرار المقبض الأول عند الضغط على الزر والآخر عند تحريره. يمكن الاستفادة من هذا برمجيًا كما لو كنت تبرمج حركةً لشخصيةٍ في لعبة، بحيث تتقدم باتجاه محدد عند الضغط على زر ثم تتوقف بمجرد أن تحرره. يمكن استخدام المقبض لتفعيل دوال بدلًا من أن يكون استخدامها محدودًا ضمن حلقة "for". احذف كل الأسطر التي تلي الدالة ()sense.clear واكتب الشيفرة التالية: def red(): sense.clear(255, 0, 0) def blue(): sense.clear(0, 0, 255) def green(): sense.clear(0, 255, 0) def yellow(): sense.clear(255, 255, 0) تحوّل هذه الدوال المصفوفة الضوئية إلى لون وحيد (أحمر أو أزرق أو أخضر أو أصفر) لتسهيل طريقة عرض برنامجك. ولكي تستدعي هذه الدوال لا بُد من تحديد أي دالة تتوافق مع أي زرٍ للمقبض، لذلك اكتب الشيفرة التالية: sense.stick.direction_up = red sense.stick.direction_down = blue sense.stick.direction_left = green sense.stick.direction_right = yellow sense.stick.direction_middle = sense.clear يحتاج البرنامج الآن إلى حلقة لا نهائية تُعرف بالحلقة الأساسية التي تُبقي البرنامج مستمرًا في عمله لمراقبة الدخل القادم إلى باي عبر مقبض سنس هات بدلًا من تنفيذ الشيفرة مرةً واحدةً ثم توقف البرنامج. اكتب الشيفرة التالية: while True: pass انقر على أيقونة التشغيل وحاول التحكم بالمقبض وستشاهد تألق المصفوفة الضوئية بألوان مختلفة، ولإطفاء الأضواء اضغط على المقبض ككل لأن الضغط على منتصفه سيستدعي الدالة ()sense.clear التي تطفئ المصفوفة. تهانينا، أصبحت قادرًا على التقاط إشارات مقبض سنس هات. مشروع سكراتش: جهاز أضواء راقصة يتعلق بالحرارة طالما أنك انطلقت في مسيرتك في عالم سنس هات فقد حان الوقت لتضع كل ما تعلمته في تصميم جهاز أضواء راقصة حساس للحرارة، وهو جهاز يكون في أوج لمعانه عندما يكون باردًا ثم يبطئ تدريجيًا عندما يسخن. ابدأ مشروعًا جديدًا في سكراتش وحمّل موّسع سنس هات من فئة "كتل إضافية More Blocks". اسحب كما جرت العادة الكتلتين و . ولا تنسَ تغيير الخيار "white" إلى "off" في الكتلة الأخيرة. سنبدأ بتصميم الجهاز البسيط بحرفية، لذلك اسحب الكتلة إلى منطقة بناء البرنامج، ثم ضع بداخلها الكتلة ثم املأ جميع فراغاتها بكتلة المعامل . يمثِّل أول مربعين فارغين الإحداثيين X و Y لموقع المؤشر الضوئي في المصفوفة لذلك لا بُد من تعديل كتلتي اختيار الرقم العشوائي في كلا الفراغين لتصبح من 0 إلى 7 بدلًا من 1 إلى 10؛ وكذلك الأمر بالنسبة للفراغات الثلاث التالية التي تمثِّل كمية اللون الأحمر ثم الأخضر ثم الأزرق، فلا بُد من تغيير مجال المتغير العشوائي ضمنها ليكون من 0 إلى 255 بدلًا من 1 إلى 10. انقر على الراية الخضراء وسترى المصفوفة الضوئية في سنس هات تضيء بألوان عشوائية. شكل 29-7 ضاءة المؤشرات الضوئية بألوان عشوائية تهانينا، لقد صنعت جهاز بريق الكتروني. لا يتفاعل هذا الجهاز مع محيطه حتى اللحظة، لذلك اسحب الكتلة وضعها تحت الكتلة ضمن الكتلة . اسحب كتلة عامل القسمة وضعها مكان الرقم 1 في كتلة الانتظار، ثم اسحب الكتلة وضعها في فراغ كتلة عامل القسمة الأول وضع 10 في الفراغ الثاني. انقر الراية الخضراء مجددًا وستلاحظ أن حدة اللمعان قد انخفضت بوضوح، إلا إذا كنت تعيش في مكان بارد جدًا، ويعود السبب وراء ذلك إلى تصميمك تأخير زمني متعلِّق بالحرارة، إذ ينتظر برنامجك عددًا من الثواني تساوي قيمة درجة الحرارة مقسومةً على 10 قبل تنفيذ ما هو موجود داخل الحلقة؛ فلو كانت درجة الحرارة 20 مئوية سينتظر البرنامج ثانيتين، وينتظر ثانية إذا كانت درجة الحرارة 10 مئوية وأقل من ثانية إذا كانت تحت 10 درجات مئوية؛ أما إن كانت القراءة سالبة (الحرارة تحت الصفر المئوي)، فلن يكون هناك تأخير زمني إطلاقًا وستُنفذ الحلقة دون تأخير. تهانينا، لقد أنجزت بنفسك برنامجًا يُكامل بين مختلف ميزات سنس هات. للاطلاع على مشاريع أخرى تستخدم سنس هات، عليك بالملحق "D" (اطلع أكثر) مشروع بايثون: مسبار ترايكوردر طالما أنك انطلقت في مسيرتك في عالم سنس هات فقد حان الوقت لتضع كل ما تعلمته في تصميم جهاز ترايكوردر Tricorder، وهو جهاز يعرفه جيدًا محبي بعض أفلام الخيال العلمي (ستار ترك تحديدًا) بأنه مسبارٌ قادرٌ على تحليل بيانات الحساسات التي يضمها. ابدأ مشروعًا جديدًا في ثوني واحفظه باسم "Tricorder" ثم اكتب الشيفرة التالية: from sense_hat import SenseHat sense = SenseHat() sense.clear() علينا في الخطوة الثانية تعريف دوال لكل حساس من حساسات سنس هات، وسنبدأ بحساسات IMU: def orientation(): orientation = sense.get_orientation() pitch = orientation["pitch"] roll = orientation["roll"] yaw = orientation["yaw"] وطالما أننا سنحرك نتائج قراءة الحساسات على شاشة المصفوفة الضوئية، فمن الأفضل تدوير القراءات إلى رقمٍ عشري واحد بعد الفاصلة حتى لا ننتظر مرور عشرات الأرقام قبل أن ننتهي من عرض أحد النتائج: pitch = round(pitch, 1) roll = round(roll, 1) yaw = round(yaw, 1) سنحتاج أخيرًا إلى تحريك النتائج على المصفوفة لأن الترايكوردر مسبارٌ محمولٌ باليد، ولا حاجة لوصله إلى شاشة. sense.show_message("Pitch {0}, Roll {1}, Yaw {2}". format(pitch, roll, yaw)) لقد انتهينا الآن من إنشاء دالةٍ تقرأ وتُظهر وجهة سنس هات بناءً على مقياس IMU، وعلينا الآن إنشاء دوال مماثلة لبقية الحساسات. لنبدأ بحساس الحرارة: def temperature(): temp = sense.get_temperature() temp = round(temp, 1) sense.show_message("Temperature: %s degrees Celsius" % temp) انتبه إلى السطر الذي يعرض النتيجة على المصفوفة الضوئية ولاحظ وجود الرمز s%، ويُدعى هذا الرمز "محدد مكان placeholder" ويُستبدل بمحتوى المتغير temp، ويساعدك ذلك على تنسيق الخرج بطريقة جميلة تظهر فيها القراءة بين عنوان "Temperature" ووحدة القياس "degrees Celsius". سننشئ الآن دالةً لحساس الرطوبة: def humidity(): humidity = sense.get_humidity() humidity = round(humidity, 1) sense.show_message("Humidity: %s percent" % humidity) ثم لحساس الضغط البارومتري: def pressure(): pressure = sense.get_pressure() pressure = round(pressure, 1) sense.show_message("Pressure: %s millibars" % pressure) وأخيرًا للبوصلة التي تعتمد على قراءة حساس الحقل المغناطيسي: def compass(): for i in range(0, 10): north = sense.get_compass() north = round(north, 1) sense.show_message("North: %s degrees" % north) استخدمنا في الدالة السابقة حلقةً قصيرةً ومحدودةً لتأخذ عدة قراءات متلاحقة من مقياس الحقل المغناطيسي للتأكُّد من كفاية البيانات لإظهار قراءة دقيقة. عدِّل مجال الحلقة إلى 20 أو 30 وحتى 100 إن شعرت بأن القراءة غير مستقرة وذلك لتحسين الدقة. يتكون برنامجك الآن من خمس دوال تقرأ كلٌ منها بيانات أحد حساسات سنس هات ثم تحرِّك هذه البيانات على المصفوفة الضوئية. بقي علينا إيجاد طريقة لنختار الحساس الذي سنعرض بياناته ومن المؤكد أن مقبض سنس هات هو الحل الأمثل. اكتب الشيفرة التالية إذًا: sense.stick.direction_up = orientation sense.stick.direction_right = temperature sense.stick.direction_down = compass sense.stick.direction_left = humidity sense.stick.direction_middle = pressure تربط الشيفرة السابقة كل حساس بأحد أزرار الاتجاه لمقبض سنس هات؛ إذ يكون الزر الأعلى لقراءة الوجهة والأسفل لقراءة مقياس الحقل المغناطيسي (البوصلة) واليمين لقراءة حساس الحرارة واليسار لقراءة الرطوبة والأوسط لقراءة الضغط. لا بُدّ أخيرًا من وضع برنامجك بأكمله ضمن حلقةٍ لا نهائية رئيسية تصغي إلى أحداث الضغط على أزرار المقبض دون أن تنهي البرنامج مباشرةً. اكتب ما يلي: while True: pass انقر على أيقونة التشغيل Run وجرِّب الضغط على أزرار المقبض لقراءة أحد الحساسات. اضغط زرًا آخر حالما ينتهي عرض القراءة السابقة وراقب النتيجة. تهانينا، لقد صممت مسبار ترايكوردر محمول باليد مكتمل الوظائف. شكل 30-7 ستتحرك كل نتيجة عبر المصفوفة الضوئية للاطلاع على مشاريع أخرى تستخدم سنس هات، عليك بالملحق "D" (اطلع أكثر). ترجمة -وبتصرف- للفصل السابع "Physical computing with Sense HAT" من كتاب The official Raspberry Pi beginner's guide. اقرأ أيضًا المقال السابق: ربط راسبيري باي بعناصر إلكترونية وبرمجتها باستخدام سكراتش وبايثون ما هو حاسوب راسبيري باي Raspberry Pi؟ التعامل مع بيئة سطر الأوامر في راسبيري باي إعداد Raspberry Pi للعمل تجميع راسبيري باي والتحضير لاستعماله
-
هل تجذبك فكرة تصميم تجربة المستخدم؟ هل كانت معرفتك بتصاميم تجربة المستخدم عبر قراءة عابرة؟ أم أنك بذلت وقتًا في الاطلاع عليها؟ إن تصميم تجربة المستخدم هي صناعة ديناميكية متداخلة التخصصات تتطور باستمرار. لن تجد أنسب من هذه الفترة لتحترف تصميم تجربة المستخدم، فهو عمل مطلوب عالميًا، مع عدد لا يُحصى من الفرص التي لن تجد عوائق كبيرةً في الحصول عليها، كما يمكنك الوصول إلى موارد هذه الصناعة من خلال الإنترنت، وستجد الكثير من الجهات التي تمنحك شهادات في تصميم تجربة المستخدم، والأهم من ذلك ما يتقاضاه مصمم تجربة المستخدم من مرتبات تفوق المتوسط بكثير. هل استرعى ما قلناه اهتمامك؟ اغتنم فرصة دمج طاقاتك الإبداعية مع إمكاناتك التحليلية لتطوير عالمنا بأفكار تصميمية جيدة. وإليك مجموعة أسباب تدفعك لتصبح مصمم تجربة مستخدم. لتترك أثرا ستعمل بصفتك مصممًا لتجربة مستخدم، على حل مشاكل حقيقية تواجه الناس في واقعهم، إضافةَ إلى بعض المنغصات الصغيرة التي تظهر يومًا بعد يوم (والتي تسبب الكثير بمجموعها). وكما يوحي الاسم "تصميم تجربة المستخدم"، فأساس هذا المجال هو المستخدم واحتياجاته، سواء أكان ما يريده تطبيقًا، أو موقع ويب، أو خدمات مالية، أو مخطط متجر. قد يعطينا سماع عبارة "تصميم تجربة مستخدم" انطباعًا عن عملاء أو تصميم وبيع منتجات، لكن ما يحدث في الواقع هو أن هذا المستخدم قد يكون مريضًا في مستشفى أو طبيبًا، وقد تكون جدتك أو حتى أنت نفسك في الكثير من المسارات. لقد امتلأ العالم بالتصاميم الجيدة والسيئة، فتخيل إذًا كيف ستتغير حياتنا إلى الأفضل إن سادت التصاميم الجيدة؟ هنا ستظهر قيمة ميزتين مهمتين لتصميم تجربة المستخدم: الشمولية inclusivity وسهولة الوصول accessibility. لقد أبدى "دون نورمان" عرّاب تصميم تجربة المستخدم ومؤلف الكتاب الذي اتسم بتصميمه القريب من المستخدم "تصميم الأشياء التي نحتاجها في حياتنا اليومية The Design of Everyday Things"، انزعاجه من عدم مراعاة المتقدمين في السن في تصميم تجارب المستخدم بعد أن أمضى 60 عامًا في المهنة. ففي مقالة لمجلة فاست كومباني Fast Company، ناقش "نورمان" -عضو مجلس إدارة IxDF ونائب رئيس شركة آبل السابق- التوجه العالمي نحو تصاميم لا تراعي المسنين إطلاقًا، خاصةً وأن البشر يُعمر في هذا العصر لفترة أطول، ويزداد متوسط أعمارهم عالميًا. صحيح أن حواس البشر تتراجع مع تقدمهم في السن وتتناقص قدراتهم الحركية، إلا أن الكثيرين منهم لا يزالون أصحاء ونشيطين. ستغدو الحياة أصعب كلما تقدمنا في العمر ابتداءً من صعوبة قراءة الخطوط الصغيرة تحت عنوان مهم أو داخل دليل استخدام، إلى غاية الحاجة إلى سكاكين وكماشات لفتح صندوقٍ يضم أدوات منزلية. وحتى عندما تُصمَّم المنتجات خصيصًا لكبار السن، إلا أنها تبدو قبيحةً وبلا معنى. أقامت الكلية الملكية للفنون معرضًا في متحف لندن للتصميم عام 2017 بعنوان "المسنون الجدد New Old"، وقد وُصف المعرض لاحقًا بمقالة كتبها أيضًا "دون نورمان" في نفس المجلة السابقة عنوانها "لماذا عليك التصميم لنفسك وكأنك في 73 من العمر Why you should be designing for your 73-year-old self". لقد أظهر المعرض أهمية التصميم الجيد وقدرته على تحسين حياتنا في آخر المطاف. ومن بين ما عرض "سكوتر لحياة بأكملها Scooter for Life" بثلاث عجلات لزيادة الاستقرار من تصميم PriestmanGoode، وقد زوّد بسلة عصرية في مقدمته لوضع البقالة، خلافًا للسكوتر التقليدي الذي نراه حولنا. "تشاهد إلى اليسار Scooter for Life من تصميم PriestmanGoode والذي يساعد كبار السن على التنقل وشراء حاجاتهم بطريقة عصرية وفعّالة أكثر. كما تشاهد إلى اليمين السكوتر التقليدي الذي لا يكاد يتسع له الممشى الجانبي للطريق، فما بالك بممرات التسوق" ينطبق الكلام السابق على المنتجات الرقمية أيضًا. فعندما تصمم تطبيقًا أو موقع ويب ليستخدمه كبار السن، لا بدّ حينها من أخذ بعض الأمور الخاصة بالحسبان، مثل الخطوط الكبيرة وأدوات التنقل الواضحة والبسيطة؛ والأهم أن يتمكن مستخدم المنتج من فهم الغاية منه بسهولة، فلن تريد لجدتك مثلًا أن تقضي ساعات محتارةً في أمر هذا التطبيق. يُوجِّه موقع الويب Ageist محتواه -الذي يهتم بنمط الحياة- إلى الأشخاص الذين تجاوزوا سن الخمسين، ويُحدَّث هذا الموقع باستمرار لتحسين تجربة المستخدم. يستخدم الموقع ألوانًا لامعةً ويمتلك أدوات تنقل بسيطة وعناصر قائمة واضحة وسهلة العرض في أعلى الصفحة، كما يعرض أيقونة بحث كبيرة. وبالإضافة إلى ذلك، لن يتطلب الوصول إلى نهاية الصفحة أكثر من دحرجتين لعجلة الفأرة. ستجني من تصميم تجربة المستخدم الشيء الكثير، وستكتشف الفرص التي لا تنتهي لتحسين وابتكار منتجات قد تحسّن حياة الملايين. لأنه عمل إبداعي ومنطقي من أكثر الأمور جاذبيةً وتفردًا في تصميم تجربة المستخدم هو التكامل بين الإبداع والمنطق. لنقل أنك شخص يصنع ما يحتاجه بيديه (إعادة استخدام وصناعات يدوية) ولديك أيضًا مدوّنة عن كيفية صناعة الأشياء بنفسك (فأنت من محبي الكتابة أيضًا). لا بد أنك شخص مبدع بالفطرة، لكنك لا تمتلك الخبرات التقنية، فسماع عبارة " كتابة شيفرة" قد تخيفك. لكن لا بأس، إذ ليس عليك أن تكون تقنيًا لتنخرط في مجال تصميم تجربة المستخدم. والأمر ذاته إن كان العكس، أي إن كانت نقاط قوتك تكمن في الرياضيات أو في كتابة الشيفرات، فسيمنحك مجال تصميم تجربة المستخدم الفرصة لاستخدام هذه القدرات وأنت تستغل ما لديك من إبداع فطري (نعم، فأنت مبدع أيضًا). ستستخدم الجانب المنطقي من تفكيرك عندما تدخل عالم تصميم تجربة المستخدم لكي تُبدع حلولًا عملية لمشاكل المستخدمين. ولن تكفي العملانية في الحلول وحسب، بل عليك أن تكون مبدعًا في الجوانب الوظيفية ونواحي الاستخدام وليس من النواحي الجمالية فقط. فكّر مثلًا بهاتفك الذكي، فهو يخدم عدة غايات عملية، أهمها الاتصالات؛ لكن ذلك ليس كافيًا للوصول إلى منتج ناجح، فما هو شعور المستخدم تجاهه؟ هل يشعر بالسعادة عند النظر إليه؟ وما الذي يجعل شخصًا ما يفضله على غيره من الهواتف الذكية؟ لنأخذ مثالًا هاتف آيفون من آبل، فهو يوازن باحتراف بين الناحيتين الجمالية والوظيفية. فقد تصادف هواتف ذكيةً بلا طرائق إعداد مفهومة وتقضي وقتك وأنت تقلب في دليل الاستخدام لفهم وظائفها، بينما تجد أن آيفون واضح الاستخدام من اللحظة التي تخرجه فيها من علبته، ويقودك بكل متعة خلال عملية الإعداد. لا تساوم إذًا بين الجمالية وسهولة الاستخدام والعكس بالعكس، فالتوازن هو الأساس. لتصبح محترفا مطلوبا في صناعة نامية متعددة الاختصاصات لا يتطلب دخولها الكثير لقد زاد عدد الموظفين المهتمين بتصميم تجربة المستخدم بما يقارب 289% عام 2020 في المملكة المتحدة. وقد وجد تقرير بعنوان "الانتباه إلى الهوة Mind the Gap " في المجلة الرقمية "Hired.com"، أن تصميم تجربة السمتخدم كانت من المهارات التي تعاني فجوةً بين العرض والطلب. وقد قدّر موقع "لينكد إن" أن تصميم تجربة المستخدم ستكون من المهارات الخمسة الأكثر طلبًا في عام 2020، كما قدّر تقرير لقناة "سي إن إن" الأمريكية عن الوظائف الأفضل مدخولًا عام 2015، أن تصميم تجربة المستخدم سينمو بمقدار 18% ما بين عامي 2015 و 2025. ستجد آلاف الوظائف المدرجة في "إنديد" و"لينكد إن" في الولايات المتحدة والمملكة المتحدة وكندا خصوصًا، مع خيارات لا تُحصى للعمل عن بعد. وستزداد بلا شك فرص العمل في تصميم تجربة المستخدم، أكثر كما سيزداد عامل الأمان فيها مع اعتناق معظم المؤسسات والمنظمات لأفكارها. رأينا أن تصميم تجربة المستخدم يُعَد مهارةً تحليليةً وإبداعية، لكنها تمتد لأبعد من ذلك حتى. يضم مجال تصميم تجربة المستخدم عددًا هائلًا من الاختصاصات المختلفة مثل علم النفس والتكنولوجيا والتصميم البصري وعلم الاجتماع، وهذا في الواقع مفهوم الاختصاصات المتنوعة multidisciplinary. تجعل هذه الميزة من العمل أكثر إثارةً ومردودًا وتحديًا ولن تقف في طريق من يريد الخوض فيه عوائق كبيرة. فلو كنت عالم نفس خلال مرحلة التدريب أو امتلكت خبرة سنوات، فستكون قادرًا على تطبيق خبراتك في مجال تصميم تجارب المستخدم، إذ لديك بالفعل الإمكانيات والمعرفة لتنطلق بقوة عندما يتعلق الأمر بفهم سلوك المستخدم، وحتى لو ابتعد مجال عملك الحالي عن تصميم تجربة المستخدم أو عن الاختصاصات التي أشرنا إليها سابقًا، فسيساعدك ما تملكه من مهارات وقدرات على البدء في مسيرتك المهنية كمصمم تجارب مستخدم. الانتقال إلى مهنة تصميم تجربة المستخدم ليس أمرا صعبا لم تتأخر بعد لتغيّر مهنتك، إذ تظهر مهن جديدة أكثر إثارةً باستمرار مع تقدم المجتمع؛ فلم يأت "دون نورمان" بمصطلح "تجربة المستخدم UX" في الواقع حتى عام 1995، ولم يتحول إلى عمل حقيقي حتى العقد الأول من هذا القرن. هنالك أسباب عديدة لتمتهن تصميم تجربة المستخدم، وستجد الكثير من الطرق التي تتبعها في سبيل ذلك. لا تجعل خلفيتك العلمية أو المهنية عائقًا في رحلتك، بل استخدمها لتنهض وتتعلم ما يلزمك لتخطو أولى خطواتك في هذا المجال، فالكثير من المهارات التي يحتاجها مصمم تجربة المستخدم الناجح قابلة للنقل من مهنة إلى أخرى، وستكون خبراتك السابقة مصدر دعم لك دائمًا. لنلق نظرة على أمثلة محددة عن كيفية الانتقال إلى مهنة تصميم تجربة المستخدم: إن كنت مصمم جرافيك فأنت محظوظ، لأن مهاراتك في التصميم الشعوري والتفكير الإبداعي وإنشاء النماذج الأولية ستخدمك جيدًا. عليك فقط التركيز على بناء أدوات فكرية تتمحور حول حاجة المستخدم، وأن تتعلم العمل على مهام متكررة ضمن فريق متعدد الاختصاصات. إن كنت مختصًا في التسويق وأردت أن تصبح مصمم تجربة مستخدم، فستساعدك مهاراتك في البحث وقدرتك على فهم علم نفس العملاء. وستجني فوائد خبراتك السابقة التي تجعل منتجًا ما مقبولًا ومرغوبًا من قِبل العميل، لكن عليك أن تغير أدواتك الفكرية التي تُركز على نسبة تحول الزوار إلى عملاء إلى أدوات تركز على تجربة المستخدم، كما عليك الاطلاع أكثر على السلوك الفردي للأشخاص. إن كنت مصمم ويب، فلا بد أنك قد اعتدت على العمل مع فريق متعدد الاختصاصات، وستتلاءم مباشرةً مع أجواء العمل. إضافةً إلى ذلك، لديك مهارات كثيرة في حل المشاكل المختلفة، وهي مهارات سهلة النقل إلى مهنة تصميم تجربة المستخدم. وكل ما عليك فعله هو تحويل تركيزك من التكنولوجيا إلى تجربة المستخدم، ولا بد من الانتباه إلى أحاسيس المستخدم عندما يتعامل مع منتج ما، إضافةً إلى التأكد من عمله من الناحية التقنية والوظيفية. إن كنت مدير أعمال، فستستفيد بالتأكيد من طريقة تفكيرك الواسعة في اتخاذ قرارات أفضل لصالح المستخدم. وما عليك فعله هو بناء أدوات فكرية تركّز على المستخدم وأن تألف عمليات ومراحل التصميم. إن كنت مطوّر برمجيات/ فهذا يعني أنك خبير في إيجاد حلول إبداعية للمشاكل واختبار هذه الحلول، كما أنك تتمتع بعقلية قابلة للتعلم باستمرار. ستساعدك هذه المهارات لتصبح مصممًا بارعًا لتجارب المستخدم. وينبغي عليك نقل تركيزك من التكنولوجيا نفسها إلى أحاسيس المستخدم عندما يتعامل معها. فإن استطعت بناء أدوات فكرية تركّز على المستخدم، فستكون ناجحًا إن امتهنت تصميم تجربة المستخدم. إن أردت تغيير مهنتك لتصبح مصمم تجربة مستخدم، وكان ما تمتهنه مختلفًا عن المهن التي ذكرناها في أمثلتنا السابقة، فلا تقلق. فكّر بالنقاط المشتركة بين مهنتك وتصميم تجربة المستخدم واستخدمها للانطلاق. وحالما تألّف أفكار تصميم تجربة المستخدم، ستمتلك وجهة نظرك الخاصة والفريدة وستبدأ في بناء مهنتك الجديدة بنجاح. ستجد الكثير من الخيارات لاكتساب المعرفة التي تحتاجها وتناسب مجالك الذي تعمل به حاليًا، وتأكد أنك تتخذ خطواتك الأولى نحو مهنة تصميم تجربة المستخدم بسلاسة وذكاء. ليس عليك أن تحترف العمل على أية أدوات صدق أو لا تصدق أن أدوات تجربة المستخدم أقل أهمية مما تعتقد، فعلى الرغم من أنها مرغوبة للمحترفين في هذا المجال ويتابعون إصداراتها الجديدة كل عام، إلا أنه من الصعب متابعتها باستمرار لتبقى على اطلاع بكل جديد. فأدوات تجربة المستخدم مثل "سكيتش Sketch" و"إن فيجين InVision" و"أدوبي إكس دي Adobe XD" مثلًا، تتطور باستمرار (بتحديثات شهرية أو أقل)/ وبالتالي سيصعب متابعتها، وسيفقدك ذلك التركيز على جوهر عملك، لكن ما تفعله وما تعرفه والخبرات التي تمتلكها وكيف تطبقّها، هي النقاط الأكثر أهميةً، فالأدوات تسطع وتخبو، لكن مبادئ تجربة المستخدم والعمليات المرتبطة بها ستبقى، ولن تضمن بقاء الأدوات التي تستخدمها حاليًا أو التي ستستخدمها مستقبلًا نفسها في مشروعك القادم أو في الشركة التي ستنتقل إليها. أخيرًا لا بد أن نشير إلى أن العديد من تقنيات تجربة المستخدم الأساسية لا تتطلب استخدام أية أدوات مثل التقنيات التي تضمن اختبارات سهولة الاستخدام والمقابلات مع العملاء. ومن أكثر المفاهيم المضللة الشائعة في مضمار تصميم تجربة المستخدم هي ضرورة معرفتك بكتابة الشيفرة. فعلى الرغم من فائدتها الواضحة للمصممين لفهم عمل التكنولوجيا التي تدعم تصميماتهم وبالتالي استخدامها باحتراف في منتجاتهم، إلا أنها ليست ضرورية. مهنة تصميم تجربة المستخدم تتيح فرصا لتطور مهنتك ومهاراتك وتخصصك تتبنى تصاميم تجربة المستخدم المهارات الفكرية والفيزيائية على حد سواء. إليك بعض المهارات التي قد تتطور عند التحول إلى مهنة تصميم تجربة المستخدم، وذلك من خلال الحصول على شهادات في تصميم تجربة المستخدم والتعلم عبر إنجاز المشاريع (هذه القائمة ليست حصرية، فهناك الكثير من المهارات المتعلقة بتصميم تجربة المستخدم والتي يمكن تعلمها): معرفة الآخرين. التفكير الناقد. البحث. التواصل البصري. الكتابة. التشفير وتطوير المنتجات الرقمية. وتمامًا كما تمكّنت من استخدام أدواتك المهارية في تصميم تجربة المستخدم، ستتمكن أيضًا من نقل مهاراتك التي ستكتسبها من تصميم تجربة المستخدم إضافةً إلى مهاراتك السابقة إلى تخصص جديد أو مجال جديد. قد يتضمن تصميم تجربة المستخدم أدورًا أو اختصاصات فرعية بما في ذلك: مصمم تجربة مستخدم. مصمم منتجات. معماري تقانة معلومات. مصمم بصري. مصمم تجربة عملاء. باحث في مجال تجربة المستخدم. محلل لاستراتيجيات المحتوى. مصمم خدمات. إن تصميم تجربة المستخدم هي مجال ابتكاري يقدّم إمكانات لا متناهية للتعلم والنمو والتطور. الحصول على شهادات في تصميم تجربة المستخدم ممكن وسهل المنال إليك المزيد من الأخبار الجيدة، ليس عليك دخول الجامعة أو أن تحصل على درجة علمية لتدخل عالم تصميم تجربة المستخدم. يمكنك أن تبدأ بالتعلم الذاتي بمساعدة بعض الموارد المتوفرة على شبكة الإنترنت. ابدأ بالبحث عن مصادر مفتوحة المصدر ومفتوحة الوصول تتحدث عن تصميم تجربة المستخدم. تساعدك الشهادات كثيرًا في مسيرتك لتحترف تصميم تجربة المستخدم، فمعرض أعمالك العصري وخبراتك أمران أساسيان لتحصين عملك الطموح كمصمم تجارب مستخدم. وتقدِم الدورات التعليمية تدريبات على إنجاز معرض أعمالك وتكسِبك خبرات من خلال تنفيذ مشاريع تطبيقية وبالتالي ستكون قادرًا على بناء معرض أعمالك أثناء تعلمك. قد يكون اختيارك لشهادة تصميم تجربة مستخدم أمرًا صعبًا لوجود خيارات كثيرة واختلاف تقييم هذه الشهادات وتضارب المعلومات حولها. ويُعَد الحل المثالي لهذا الأمر هو البحث الذاتي والتساؤل المستمر للتأكد من أن ما تختاره سيحقق أهدافك ومتطلباتك. هل أنت مستعد لتبدأ رحلتك في تصميم تجربة المستخدم؟ تحقق من الدورات التعليمية المعترف بها في هذه الصناعة، وكذلك الدروس الاحترافية ومعسكرات التدريب التي يشرف عليها مختصون. يمكنك الاختيار ما بين العديد من المواد التعليمية والمبنية بطرق مختلفة لتلائم أسلوبك الخاص في التعلم، وستتعمق في تفاصيل مفاهيم تجربة المستخدم عبر الشهادات المعترف بها في هذه الصناعة. وإن كان الوقت هو ما يقيّدك، فالدروس الاحترافية Master Classes التي لا تستغرق أكثر من ساعة هي وسيلتك لتخوض غمار تجربة المستخدم دون أن تلتزم بفترة زمنية محددة. بإمكانك أن تعمل عن بعد لقد أجبرت ظروف الجائحات التي ظهرت في السنوات الأخيرة، وأبرزها جائحة كوفيد 19، الكثيرين على العمل عن بعد. وقد شجعت التداعيات الاقتصادية للوباء والحاجة الملحة لاستمرار العمل، الكثير من الهيئات على تقليل نفقاتها العامة وتوفير الوقت والموارد بتبني العمل الافتراضي تمامًا. وقد خطى بعضها خطوات متقدمة جدًا بالتخلص من مكاتبها الحقيقية بالكامل. لقد جعلت الكثير من مواقع الويب مثل Zoom وSlack وMicrosoft Teams العمل عن بعد مباشرًا وأكثر تطورًا عما كان عليه، ولا حاجة فيما يخص مصممي تجارب المستخدم التواجد فيزيائيًا في مكان محدد، فكل ما يحتاجونه هو حاسوب واتصال بالإنترنت وورقة وقلم للبدء بالتصميم، ويمكنهم التواصل مع الزملاء أو العملاء أو ينفّذوا أية مهام مطلوبة من خلال تلك المنصات. لا ضمانة طبعًا أن تنتقل لشركة تصميم تجربة المستخدم التي قد تعمل لحسابها إلى العمل عن بعد، لكن فرص حدوث ذلك في الواقع تزداد أكثر في كل سنة. وإن كنت تعمل مستقلًا، فسيعود إليك خيار انتقاء الطريقة المناسبة لإنجاز أعمالك. ستحصل على مرتب كاف إن أحد الأسباب التي تجعلك مقتنعًا بعملك هو أن يكون عملًا ذو معنى (إن لم يكن السبب الرئيسي)، كما أن ما تتقاضاه ماديًا أمر مهم أيضًا، فإن لم تشعر بأن عملك الجاد قد آتى ثماره، ستبدأ البحث عن فرص أخرى حتى لو كنت مستمتعًا بما تفعله. يزداد الطلب على مصممي تجربة المستخدم بشدة، وهنالك نقص في أعدادهم، وبالتالي سيزداد متوسط مرتبات المصممين. تختلف المرتبات غالبًا تبعًا للدول والشركات ومستوى الخبرة وعوامل أخرى، إذ يبلغ المتوسط السنوي في الولايات المتحدة قرابة 105,122 دولار أمريكي و 48,755 جنيه استرليني في المملكة المتحدة و 77,090 دولار كندي في كندا و 1,389,256 روبية في الهند. سيزداد الطلب على مصممي تجربة المستخدم في اﻷعوام القادمة عالميًا، وبالتالي ستزداد مرتباتهم. تدفع شركات تصميم تجارب المستخدم أكثر للخبراء، لذلك توّقع أن يزداد ما تتقاضاه مع نمو خبراتك. خلاصة القول تقدم لك مهنة مصمم تجارب المستخدم فرصًا مهمةً ومستمرةً في النمو وجميعها في متناول يديك. ومع النقص في أعداد المصممين عالميًا سترتفع المرتبات وتنخفض متطلبات دخول المهنة. ومع حرية العمل في أي مكان تفضّله، سيكون المستقبل مثاليًا لتجرب هذا الطريق. لا تقلق إن لم تمتلك خلفيةً في التصميم أو بأنظمة المعلومات، إذ ستجد الكثير من الدورات ومعسكرات التدريب والمناهج المعترف بها في هذه الصناعة بانتظارك لتبدأ رحلتك في عالم تصميم تجربة المستخدم. ومع المشكال العصرية التي ظهرت وستظهر دائمًا فهي التجارة الرابحة في هذا العصر، ويمكنك التنقل ضمن قسم التصميم من أكاديمية حسوب ترجمة -وبتصرف- للمقال 10 Reasons To Become A UX Designer in 2022 لصاحبته Molly Fitz-Patrick. اقرأ أيضًا مهام مصممي تجربة المستخدم مخرجات تصميمية يجب على كل مصمم تجربة مستخدم أن يتقنها دليلك الشامل لفهم المسارات المهنية لمجال تجربة المستخدم
-
يستخدِم المتصفح خيطًا واحدًا افتراضيًا لتنفيذ شيفرة جافاسكربت في صفحتك، إضافةً إلى تخطيط الصفحة وإعادة ضبط العناصر وتجميع الموارد المستهلكة، ويعني هذا أنّ التنفيذ الطويل لدوال جافاسكربت قد يعيق خيط التنفيذ، والذي يقود بدوره إلى صفحة ضعيفة الاستجابة، وبالتالي تجربة مستخدِم سيئة، كما تستطيع استخدام أداتَي تحليل الأداء Waterfall وFrame rate الموضحتين في مقال المكونات الرئيسية للأداة Performance لتحليل أداء صفحات الويب لمراقبة تنفيذ جافاسكربت والمشاكل التي تسببها في الأداء والإشارة إلى دوال محددة تستدعي الانتباه. سنستخدِم في هذا المقال مثالًا لموقع يسبب فيه التنفيذ الطويل لجافاسكربت عدم الاستجابة، وسنقدِّم بعد ذلك مقاربتين مختلفتين لحل هذه المشكلة، بحيث تقتضي الأولى ضرورة فصل الدوال التي تستغرق وقتًا طويلًا في التنفيذ إلى أجزاء واستخدام الدالة ()requestAnimationFrame لجدولة تنفيذ هذه القطع؛ أما الثانية، فهي تنفيذ الدالة كلها في خيط مستقل مستخدِمين عمّال ويب، ولتجريب المثال التطبيقي يمكنك إيجاده في المستودع الخاص به على جيت هاب، إذ سيبدو هذا الموقع بالصورة التالية: يتضمن الموقع ثلاث أدوات تحكم: مجموعة أزرار اختيار للتحكم بطريقة تنفيذ شيفرة جافاسكربت: على أساس كتلة واحدة ضمن الخيط الرئيسي. على أساس سلسلة من عمليات أصغر ضمن الخيط الرئيسي باستخدام ()requestAnimationFrame. ضمن خيط مستقل باستخدام عمّال ويب. زر لتنفيذ شيفرة جافاسكربت عنوانه "!Do pointless computations". زر لتشغيل وإيقاف بعض رسوم CSS المتحركة لكي ينفِّذ المتصفح بعض الأعمال خلف الستار. ابقي الخيار على التنفيذ على أساس كتلة واحدة ضمن الخيط الرئيسي Use blocking call in main thread، واستعد لتسجيل ملف أداء عبر الأداة Performance. انقر على زر Start animations. ابدأ بتسجيل ملف الأداء. انقر على زر Do pointless computations! مرتين أو ثلاث مرات. أوقف تسجيل الملف. سيختلف ما تراه ضمن نافذة الأداة Performance تبعًا لحاسوبك، لكنه يبدو مشابهًا للقطة الشاشة التالية: يعرض القسم الأعلى من اللقطة نظرة عامة للأداة Waterfall يخبرنا عن نوع العمليات التي يجريها المتصفح خلال فترة التسجيل، حيث يدل اللون الزهري على أنّ أغلب ما ينفذه المتصفح هي حسابات خاصة بتنسيق CSS وقد تجد بعض عمليات تخطيط الصفحة وإعادة تدفقها وجمع البيانات المهملة، إذ ينتج ذلك عن رسوميات CSS المتحركة التي تُنفَّذ خلال فترة تسجيل ملف الأداء، وسترى أيضًا كتلًا برتقالية اللون تمثِّل شيفرة جافاسكربت التي تُنفَّذ في كل مرة ننقر فيها الزر، في حين نشاهد في القسم السفلي معدل الإطارات المرتبط بالمسار الزمني للتسجيل، إذ يمكننا رؤية أنّ معدل الإطارات سليم طيلة فترة التسجيل، لكنه ينهار تمامًا عند النقر على الزر، كما سنختار إحدى هذه الفترات ونلقي نظرةً عن قرب على ما يجري من خلال نافذة التفاصيل التي تعرض بيانات الأداة Waterfall: يُنفِّذ المتصفح دالة جافاسكربت أو سلسلة من الدوال الأصغر عندما نضغط الزر، مما يعيق التنفيذ ضمن الخيط الرئيسي مدة 71.73 ميلي ثانية، إذ يُعَدّ هذا الزمن أعلى بأربع مرات من الزمن المفترض لتنفيذ الإطار أي 16.7 ميلي ثانية، فما الدالة التي سببت المشكلة إذًا؟ لننتقل إلى الأداة Flame Chart لنرى تفاصيلًا أكثر ضمن نافذة التفاصيل: تعرض لنا الأداة مكدس استدعاء جافاسكربت في لحظة التنفيذ هذه، إذ تتوضع الدالة ()calculatePrimes في قمة المكدس، كما يمكننا من خلال التفاصيل المعروضة معرفة اسم الملف الذي يضمها والسطر الذي عُرّفت فيه، وإليك شيفرة الدالة، بالإضافة إلى الدالة التي تستدعيها مباشرةً: const iterations = 50; const multiplier = 1000000000; function calculatePrimes(iterations, multiplier) { var primes = []; for (var i = 0; i < iterations; i++) { var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } return primes; } function doPointlessComputationsWithBlocking() { var primes = calculatePrimes(iterations, multiplier); pointlessComputationsButton.disabled = false; console.log(primes); } ما تنفذه الشيفرة هو اختبار -غير فعال إطلاقًا- لأوّليِّة primality عدد عشوائي كبير ويُكرَّر الاختبار 50 مرة. استخدام الدالة requestAnimationFrame سنقسم الدالة إلى عدد من الدوال الأصغر والمستقلة بذاتها على أساس محاولة أولى لحل المشكلة، وسنستخدِم بعد ذلك الدالة ()requestAnimationFrame لجدولة تنفيذ هذه الأجزاء، إذ تطلب هذه الدالة من المتصفح تنفيذ دالة محددة في كل إطار قبل عملية إعادة رسم الصفحة مباشرةً. وطالما أن الدوال المجتزأة صغيرة بما يكفي، فسيتمكن المتصفح من تنفيذ العمل ضمن الزمن المفترض لكل إطار، كما أنه من السهل تجزئة الدالة ()calculatePrimes بحيث تحسب أوّليّة كل عدد في دالة مستقلة: function doPointlessComputationsWithRequestAnimationFrame() { function testCandidate(index) { // finishing condition if (index == iterations) { console.log(primes); pointlessComputationsButton.disabled = false; return; } // test this number var candidate = index * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } // schedule the next var testFunction = testCandidate.bind(this, index + 1); window.requestAnimationFrame(testFunction); } var primes = []; var testFunction = testCandidate.bind(this, 0); window.requestAnimationFrame(testFunction); } انتقل إلى الخيار Use requestAnimationFrame لاختبار هذا الحل، ثم ابدأ تسجيلًا جديدًا، إذ سيبدو التسجيل هذه المرة مشابهًا للقطة الشاشة التالية: ما نراه في اللقطة هو ما نتوقعه تمامًا، فبدلًا من ظهور كتلة برتقالية واحدة في كل مرة ننقر فيها على الزر، سنجد سلسلةً طويلةً مكونةً من كتل برتقالية قصيرة جدًا تبدو منفصلة عن بعضها بمقدار إطار -أي زمن تنفيذ إطار- وتمثِّل كل منها تنفيذ دالة واحدة من الدوال التي تستدعيها ()requestAnimationFrame، كما يتخلل الكتل البرتقالية كتلًا زهرية اللون تمثِّل عمليات CSS، وسيتمكن المتصفح من تنفيذ عمليات الإطار جميعها في الوقت المفترض دون انخفاضات مفاجئة عند نقر الزر -عند تنفيذ جافاسكربت- نظرًا لصغر فترة تنفيذ الدوال المجزَّأة. حسّن استخدام الدالة ()requestAnimationFrame استجابة الموقع، لكن هناك مشكلتَين محتملتَين: من الصعب أحيانًا تقسيم الدالة التي تتطلب وقتًا كبيرًا في التنفيذ إلى دوال مستقلة أصغر، فقد ولَّدت هذه العملية في مثالنا البسيط شيفرةً أعقد. تستغرق الدوال المجزأة وقتًا أطول حتى تُنفَّذ جميعها، إذ يمكن في مثالنا تحديد الوقت الذي استغرقته بدقة: إذ تُكرَّر العملية 50 مرة، ويولّد المتصفح 60 إطار في الثانية، وبالتالي سيستغرق تنفيذ التكرارات الخمسين قرابة الثانية، وهذا الزمن ملحوظ سواء في ملف الأداء أو من قبل المستخدِم. استخدام عمال ويب سنحاول حل المشكلة الآن باستخدام تقنية عمَّال الويب التي تمكّنك من تنفيذ شيفرة جافاسكربت في خيط مستقل، ولا يمكن بالطبع استدعاء دوال تُنفَّذ ضمن الخيط الرئيسي من خيط العامل أو العكس مباشرةً، وإنما يمكنها التواصل من خلال واجهة برمجية تضمن تراسلًا غير متزامن، وتبدو الشيفرة التي تُنفَّذ ضمن الخيط الرئيسي كما يلي: const iterations = 50; const multiplier = 1000000000; var worker = new Worker("js/calculate.js"); function doPointlessComputationsInWorker() { function handleWorkerCompletion(message) { if (message.data.command == "done") { pointlessComputationsButton.disabled = false; console.log(message.data.primes); worker.removeEventListener("message", handleWorkerCompletion); } } worker.addEventListener("message", handleWorkerCompletion, false); worker.postMessage({ "multiplier": multiplier, "iterations": iterations }); } إنّ الاختلاف الرئيسي في هذه الحالة موازنةً بالسابقة هو الحاجة إلى: إنشاء عامل. إرسال رسالة عندما يحين وقت الحسابات. الإنصات إلى رسالة نصها "done" تشير إلى انتهاء العامل. نحتاج بعد ذلك إلى ملف يُدعى calculate.js ويضم الشفرة التالية: self.addEventListener("message", go); function go(message) { var iterations = message.data.iterations; var multiplier = message.data.multiplier; primes = calculatePrimes(iterations, multiplier); self.postMessage({ "command":"done", "primes": primes }); } function calculatePrimes(iterations, multiplier) { var primes = []; for (var i = 0; i < iterations; i++) { var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } return primes; } لا بد في شيفرة العامل أن ننصت إلى الرسالة التي تخبرنا ببدء التنفيذ، ومن ثم نرسل الرسالة "done" عندما ننهي الحسابات. لاحظ أنّ الشيفرة التي تنفّذ الحسابات هي نفسها تمامًا الشيفرة الأصلية دون تعديل، فكيف سيتغير الأداء الآن؟ انتقل إلى الخيار Use a worker وأنشئ تسجيلًا جديدًا، إذ سيبدو التسجيل مشابهًا للقطة الشاشة التالية: نقرنا الزر في هذا التسجيل ثلاث مرات، حيث تبدو كل نقرة موازنةً بالملف الأول كتلتَين برتقاليتَي اللون وقصيرتين جدًا هما: الدالة ()doPointlessComputationsInWorker التي تتعامل مع حدث النقر وتبدأ تنفيذ شيفرة عامل الويب. الدالة ()handleWorkerCompletion التي تُنفَّذ عندما ينتهي استدعاء العامل. سينفِّذ العامل اختبارات الأوّليّة في الفترة الفاصلة بين تنفيذ الدالتين السابقتين ولم يلاحظ أيّ تأثير على استجابة الخيط الرئيسي، وقد يبدو هذا الأمر مستبعدًا بعض الشيء، لكن قد تستغل تقنية عمال الويب إيجابيات المعالجات متعددة النوى كونها تعمل على خيط مختلف، في حين لا يمكن للمواقع التي تعتمد خيطًا واحدًا استغلال هذه الناحية في تحسين الأداء، وتبقى المحدودية الرئيسية لاستخدام عمال ويب هي عدم توفر واجهة برمجية لشجرة DOM لدعم عملياتها. ترجمة -وبتصرف- للمقال Intensive Javascript. اقرأ أيضًا المقال السابق: تأثير رسوم CSS المتحركة على أداء مواقع الويب خطوات أساسيّة لتحسين أداء المواقع
-
قد ترغب في نشر صفحة الويب البسيطة التي بنيتها ليزورها الجميع وذلك برفعها إلى خادم ويب، لهذا سنناقش في هذا المقال طريقة تنفيذ الأمر مستخدِمين عدة خيارات وأدوات متاحة، مثل عميل SFTP وRSync وGitHub وGoogle App Engine، كما يُنصح قبل متابعة القراءة بالاطلاع على مفهوم خادم الويب وآلية عمل أسماء النطاقات، كما ينبغي أن تكون على دراية بطريقة إعداد بيئة عمل بسيطة من أجل تطوير الويب وكيفية كتابة صفحات ويب. بروتوكول نقل الملفات الآمن SFTP ستجد العديد من الأدوات التي تخدم مثل عميل لبروتوكول SFTP، وسنغطي في مقالنا FileZilla كونها أداةً مجانيةً متاحةً للاستخدام في ويندوز وماك ولينوكس، ولتثبيت الأداة FileZilla، انتقل إلى صفحة التنزيل الرئيسية الخاصة بها، ثم انقر الزر الكبير الذي يحمل العنوان تنزيل Download، بعد ذلك ثبتها من خلال ملف التثبيت الذي نزّلته بالطريقة الاعتيادية. افتح تطبيق FileZilla وسترى نافذةً تشبه النافذة في الصورة التالية: تسجيل الدخول سنفترض في مثالنا أنّ مزود خدمة الاستضافة -أي الخدمة التي تستضيف خادم ويب HTTP الخاص بنا- هي الشركة الوهمية "Example Hosting Provider" التي تعطي لمواردها عناوين URL. لنفترض أننا أنشأنا حسابًا وتلقينا المعلومات التالية: لنلق نظرةً في البداية على العنوان /http://demozilla.examplehostingprovider.net، وبالطبع لن تجد شيئًا فيه. اتبع الآن الخطوات التالية لتتصل بالخادم البعيد عبر عميل SFTP الذي ثبتّه: اختر من القائمة الرئيسية: ملف File > مدير الموقع Site Manager. انقر على الزر "موقع جديد New Site" في نافذة "مدير الموقع Site Manager" وسمِّ الموقع "demozilla" ضمن المساحة المخصصة لذلك. ضع في حقل "المضيف Host" اسم خادم SFTP الذي زودتك به الشركة. اختر "عادي Normal" من قائمة نمط تسجيل الدخول Logon Type المنسدلة، ثم اكتب اسم المستخدِم وكلمة المرور في الأماكن المخصصة لذلك. ضع رقم المنفذ وبقية المعلومات المطلوبة في أماكنها المخصصة. انقر الآن على زر "اتصال Connect" لتتصل بالخادم. العرض المشترك للموارد على حاسوبك وعلى الخادم ستبدو نافذة التطبيق كما يلي عند نجاح الاتصال بالخادم، والصورة التالية ما هي إلا مثال خاص لإيضاح الفكرة فقط: لنلق نظرةً على ما تعرضه الصورة: ستجد في القسم اليساري نافذة الملفات المحلية، حيث تستطيع من خلالها الانتقال إلى المجلد الذي تخزّن فيه موقعك. ستجد في القسم اليميني اليساري نافذة الملفات الموجودة على الخادم -أي البعيدة- بعد دخولنا إلى المجلد الخاص بالموقع على الخادم عبر بروتوكول SFTP. يمكنك تجاهل الأقسام العليا والسفلى حاليًا، وهي بالترتيب نافذة سجل الرسائل التي تعرض حالة الاتصال بين حاسوبك وخادم SFTP، وتمثل الأخرى سجلًا آنيًا لمعلومات التفاعل بين عميل SFTP الخاص بك والخادم. رفع الموارد إلى الخادم تخبرنا إرشادات خادم الاستضافة في مثالنا أنه علينا وضع الموارد في المجلد البعيد Public/htdocs حتى تُنشَر على الويب، إذًا لا بدّ من الانتقال إلى المجلد المحدَّد ضمن القسم اليساري من نافذة العميل. ويمثِّل هذا المجلد جذر موقع الويب، إذ ينبغي وجود الملف الرئيسي للموقع index.html، وبقية الموارد الداعمة له ضمن هذا المجلد، وعندما تصل إلى المجلد الجذر، اسحب الملفات والموارد التي تريد رفعها إلى الخادم من القسم الأيسر لنافذة العميل إلى القسم الأيمن من النافذة. التحقق من وجود الملفات على ويب بعد رفعها يمكنك التحقق من وجود الملفات التي رفعتها بطلب عنوان موقعك عبر المتصفح في مثالنا. /http://demozilla.examplehostingprovider.net وبهذا تكون العملية قد اكتملت بنجاح. استخدام الأداة Rsync تُستخدَم الأداة Rsync لمزامنة الملفات المحلية والبعيدة، وتتوفر الأداة عمومًا في معظم الأنظمة المبنية على يونكس مثل ماك ولينوكس، كما تتواجد نسخ تعمل على ويندوز أيضًا، ويُنظَر إلى هذه الأداة على أنها أكثر تقدمًا من عملاء SFTP لأنها تستخدَم في سطر الأوامر افتراضيًا، إذ يبدو الأمر الأساسي كما يلي: rsync [-options] SOURCE user@x.x.x.x:DESTINATION -options: وهي عبارة عن شرطة - يتبعها حرف أو أكثر مثل v- لإظهار رسائل الخطأ الطويلة وb- لإجراء نسخ احتياطي، كما يمكنك الاطلاع على قائمة الخيارات ضمن الصفحة الرئيسية للأداة Rsync. SOURCE: يمثِّل المسار إلى الملف أو المجلد المحلي الذي تريد نسخ الملفات منه. @user: يمثِّل ثبوتيات المستخدِم على الخادم البعيد الذي تريد نسخ الملفات إليه. x.x.x.x: عنوان IP الخاص بالخادم البعيد. DESTINATION: يمثِّل المسار أو الموقع على الخادم البعيد الذي تريد نسخ الملفات أو المجلدات إليه. عليك الحصول على المعلومات السابقة من مزود خدمة الاستضافة، كما من الجيد دائمًا استخدام اتصال آمن كما هو الحال مع FTP، لذلك يمكن تحديد التفاصيل الخاصة ببروتوكول SSH لتنفيذ الاتصال باستخدامه من خلال الخيار e-، وإليك المثال التالي: rsync [-options] -e "ssh [هنا SSH ضع تفاصيل]" SOURCE user@x.x.x.x:DESTINATION واجهات رسومية للأداة Rsync أدوات الواجهات الرسومية متوفرة لهؤلاء الذين لا يرتاحون بالتعامل مع سطر الأوامر مثل الأداة Acrosync المتاحة في نظامَي التشغيل ويندوز وماك، وتذكَّر أنه عليك الحصول على الثبوتيات اللازمة للوصول إلى موقعك من خادم الاستضافة، إذ سيكون دور الواجهة الرسومية تسهيل إدخال هذه الثبوتيات. نشر موقع ويب على جيت هاب GitHub يُعَدّ جيت هاب GitHub موقع ويب لكتابة الشيفرة بصورة جماعية، حيث يمكّنك من رفع الشيفرة وتخزينها في مستودعات منظومة إدارة النُسخ الخاصة بالموقع، كما يتيح لك هذا الموقع المفتوح المصدر لاحقًا إمكانية التعاون مع أطراف أخرى للعمل على شيفرتك، حيث يمكن لأيّ كان الوصول إلى شيفرتك واستخدامها والتعلم منها وتطويرها أيضًا، كما يمكنك بالطبع فعل الأمر ذاته مع أيّ شيفرة ضمن الموقع، وسيرشدك هذا المقال إلى كيفية نشر المحتوى على الويب باستخدام الميّزات التي تقدمها صفحات جيت هاب GitHub-pages. نشر المحتوى يُعَدّ جيت هاب مجتمعًا غايةً في الأهمية والفائدة، كما تُعَدّ جيت Git منظومة إدارة نُسخ شعبيةً جدًا تستخدِمها معظم الشركات حاليًا أثناء تطوير برمجياتها، كما يمتلك جيت هاب ميزةً هامةً تُدعى صفحات جيت هاب تتيح لك نشر شيفرة المواقع على الويب مباشرةً. الإعدادات الأساسية ثبّت جيت أولًا على حاسوبك، فهي البنية البرمجية التحتية لمنظومة إدارة النسخ ويعمل جيت هاب اعتمادًا عليها. سجّل بعد ذلك حسابًا جديدًا على جيت هاب، وهذه العملية بسيطة وسهلة. سجّل دخولك إلى الموقع عندما يكتمل حسابك الجديد باستخدام كلمة السر واسم المستخدِم الخاصَّين بك. تحضير الشيفرة لرفعها يمكنك تخزين الشيفرة التي تريد في مستودعات جيت هاب، لكن لا بدّ من تنظيم شيفرتك على أساس شيفرة موقع ويب تقليدي حتى تستفيد من ميزة صفحات جيت هاب بكامل طاقتها، إذ ينبغي مثلًا وجود نقطة دخول إلى موقعك على شكل ملف HTML يحمل الاسم index.html، كما يجب أيضًا تهيئة مجلد الشيفرة ليصبح مستودع جيت قبل متابعة العمل، واتبع الخطوات التالية لتنفيذ الأمر: انتقل من خلال سطر الأوامر إلى المجلد الذي يحتوي على موقعك مستخدِمًا تعليمة تغيير المجلد cd وسنفترض أنه يحمل الاسم test-site وموجود على سطح المكتب: cd Desktop/test-site نفّذ التعليمة التالية عندما تصل إلى داخل المجلد المطلوب، والتي تطلب من الأداة git تحويل مجلدك إلى مستودع جيت: git init واجهات سطر الأوامر ستكون أفضل الطرق لرفع الشيفرة إلى جيت هاب هي عبر سطر الأوامر، إذ سيظهر على صورة نافذة تكتب فيها التعليمات التي تنفذ وظائف معينة مثل إنشاء ملفات أو تنفيذ برنامج معيّن، بدلًا من النقر على أزرار واجهة مستخدِم ما، وستبدو نافذة سطر الأوامر مشابهةً للصورة التالية: يحتوي أي نظام تشغيل على أداة سطر الأوامر: ويندوز: وتُدعى موجِّه الأوامر Command Prompt، ويمكن الوصول إلى الأداة بالضغط على المفتاح Windows ثم كتابة Command Prompt واختياره من القائمة التي ستظهر، وتذكّر أنّ سطر أوامر ويندوز مختلف عن مثلائه في لينوكس وماك، لذلك قد تختلف التعليمات التي ستراها تاليًا وفقًا لنظام التشغيل. OS X: وتُدعى طرفية Terminal، وللوصول إليها انتقل إلى تطبيقات Applications، ثم مرافق Utilities. لينوكس: وتُدعى طرفية Terminal أيضًا، ويمكن الوصول إليها عادةً بضغط المفاتيح Ctrl + Alt + T، وإذا تعذر ذلك، فابحث عنها ضمن شريط التطبيقات أو في القائمة. قد يخيفك الأمر في البداية، لكنك ستعتاد على هذه المهام الروتينية، فكل ما عليك فعله هو إخبار الحاسوب بما تحتاج من خلال كتابة الأمر المناسب ثم الضغط على المفتاح Enter. بناء مستودع خاص بشيفرتك لا بدّ من إنشاء مستودع جديد لملفاتك على أساس خطوة ثانية. انقر على زر الإضافة (+) في أعلى يمين صفحة جيت هاب الرئيسية، بعد ذلك اختر مستودعًا جديدًا. اكتب اسم المستودع المناسب لشيفرتك في صندوق اسم المستودع Repository name عندما تنتقل إلى صفحة إنشاء مستودع جديد، ليكون مثلًا my-repository. اكتب معلومات عن المحتويات التي ستضعها في المستودع في حقل الوصف Description كما في الصورة التالية: انقر على زر إنشاء مستودع Create repository وستظهر لك الصفحة التالية: رفع الملفات إلى جيت هاب سترى سطرين من الشيفرة في صفحة المستودع الجديد وفق القسم الذي يحمل العنوان "… أو ادفع مستودعًا موجودًا عبر سطر الأوامر or push an existing repository from the command line…"؛ انسخ السطر الأول بالكامل والصقه في نافذة سطر الأوامر، ثم اضغط المفتاح Enter، إذ سيبدو الأمر مشابهًا للصورة التالية: git remote add origin https://github.com/chrisdavidmills/my-repository.git اكتب سطرَي الأوامر التاليين ثم اضغط المفتاح Enter بعد كل سطر، حيث تحضِّر التعليمات السابقة الشيفرة للرفع إلى جيت هاب وتطلب من جيت إدارة ملفات الشيفرة. git add --all git commit -m 'adding my files to my repository' ادفع الشيفرة في النهاية إلى جيت هاب بالانتقال إلى صفحة الويب جيت هاب التي كنا فيها، ثم أدخل السطر الثاني من الشيفرة الموجودة في القسم "… أو ادفع مستودعًا موجودًا عبر سطر الأوامر or push an existing repository from the command line…" إلى الطرفية أو موجِّه سطر الأوامر واضغط المفتاح Enter. git push -u origin main علينا الآن تفعيل ميزة صفحات جيت هاب في المستودع الجديد الذي رفعت إليه ملفات الشيفرة، لذلك اختر الأمر "إعدادات Setting" في صفحة الويب الخاصة بمستودعك ثم الأمر "صفحات Pages" من الشريط الجانبي على يسار الصفحة، واختر بعد ذلك الفرع "رئيسي Main" أسفل الأمر مصدر Source، إذ سيسبب ذلك تحديث الصفحة. انتقل إلى قسم صفحات جيت هاب مجددًا، وسترى سطرًا جديدًا مفاده أنّ موقعك أصبح جاهزًا ليُنشر على العنوان https://xxxxxx. إذا نقرت على عنوان URL السابق، فستنتقل إلى نسخة حية لموقعك تُعرض فيها محتويات الصفحة التي تُدعى index.html، والتي تُعرض افتراضيًا؛ لكن إذا كانت الصفحة الرئيسية لموقعك لا تحمل الاسم السابق وإنما myPage.html مثلًا، فعليك حينها الانتقال إليها بنفسك بطلب عنوانها https://xxxxxx/myPage.html. معلومات أكثر عن جيت هاب إذا أردت إجراء تعديلات أكثر على موقعك ومن ثم رفع الشيفرة المعدَّلة إلى جيت هاب، فعليك تطبيق التغييرات التي أجريتها سابقًا على ملفات موقعك كما فعلت سابقًا، ثم إدخال الأوامر التالية مع الضغط على المفتاح"Enter" بعد كل أمر لدفع التعديلات إلى جيت هاب: git add --all git commit -m 'another commit' git push ضع مكان العبارة another commit أيّ رسالة أخرى تراها مناسبة لوصف التعديلات التي أجريتها. يُعَدّ ما قدمناه عن جيت بدايةً متواضعةً جدًا، ولتتعمق أكثر عليك الاطلاع على المزيد من المقالات والدورات التعليمية حول جيت وجيت هاب. استضافة مواقع ويب على محرك جوجل آب يُعَدّ محرك جوجل آب Google App Engine منصةً فعالةً لبناء وتشغيل التطبيقات بالاستفادة من البنية التحتية لجوجل، سواءً أردت بناء موقع ويب من الصفر، أو استضافة موقع ويب ساكن static website، كما سنرشدك فيما يأتي إلى طريقة استضافة موقعك على جوجل آب خطوةً بخطوة. إنشاء مشروع على منصة جوجل السحابية لا بدّ من إنشاء مشروع جديد على منصة جوجل السحابية Google Cloud Platform قبل البدء باستخدام أدوات جوجل، ويتطلب ذلك بالطبع امتلاك حساب على جوجل. انتقل إلى لوحة محرك التطبيقات App Engine dashboard ضمن طرفية منصة جوجل السحابية، وانقر زر إنشاء Create. إذا لم تنشئ مشروعًا من قبل، فعليك تحديد ما إذا أردت استقبال بريد إلكتروني عن آخر التحديثات أم لا، ثم الموافقة على شروط الخدمة. ويفترض بعدها أن تكون قادرًا على متابعة العمل. اختر اسمًا للمشروع ثم اعدل على معرفه ID، واحفظه، إذ سنستخدِم القيم التالية في هذه الإرشادات: اسم المشروع: GAE Sample Site. معرّف المشروع: gaesamplesite. انقر على زر إنشاء Create لإنشاء مشروعك. إنشاء تطبيق يمكن أن يضم كل مشروع سحابي تطبيقًا واحدًا وهذا ما سنفعله الآن: نحتاج إلى تطبيق تجريبي لننشره، فإذا لم يكن لديك تطبيق لاستخدامه، فنزِّل التطبيق التجريبي الذي أعددناه لهذا الغرض وفك ضغطه. لنلق نظرةً على هيكلية التطبيق التجريبي، حيث يحتوي المجلد website على ملفات المشروع بالإضافة إلى ملف الإعدادات app.ymal. لا بدّ أن تكون محتويات موقعك ضمن المجلد website وأن تحمل الصفحة الرئيسية للموقع الاسم index.html وما عدا ذلك يمكنها أخذ الشكل الذي تريد. يخبر ملف الإعدادات app.yaml محرك التطبيقات عن كيفية ربط العناوين التي تقود إلى ملفاتك الساكنة، ولا حاجة لتعديل أيّ شيء فيه. نشر التطبيق سنحاول نشر التطبيق التجريبي الآن بعد تجهيزنا إياه: افتح مفسّر أوامر أو صدفة سحابة جوجل Google Cloud Shell. اسحب المجلد sample-app وافلته في لوحة محرر الشيفرة. نفِّذ الأمر التالي لاختيار مشروعك: gcloud config set project gaesamplesite نفّذ الأمر التالي للانتقال إلى مجلد تطبيقك: cd sample-app بهذا تكون قد أصبحتَ جاهزًا الآن لنشر التطبيق، أي لرفع تطبيقك إلى محرك تطبيقات جوجل: gcloud app deploy أدخِل رقمًا ليدل على المنطقة التي ستضع فيها تطبيقك. اضغط المفتاح Y لتأكيد ما اخترته. انتقل إلى تطبيقك عبر المتصفح بكتابة عنوانه على الصورة your-project-id.appspot.com لمشاهدة موقعك على الإنترنت، وسنستبدل your-project-id في تطبيقنا التجريبي بمعرِّف التطبيقgaesamplesite ليصبح العنوان على الصورة gaesamplesite.appspot.com. طرق أخرى لرفع الملفات يّعَدّ بروتوكول FTP من البروتوكولات المعروفة جيدًا لنشر مواقع الويب، لكنه بالطبع ليس الوحيد في هذا المضمار، وإليك بعض الخيارات الأخرى: واجهات ويب Web interfaces: وهي واجهة مكتوبة بلغة HTML تعمل على أساس واجهة أمامية لخدمة رفع ملفات عن بعد موجودة على خادم الاستضافة. WebDAV: وهو توسعة لبروتوكول HTTP يسمح بإدارة أوسع للملفات. اقرأ أيضا اطلع على توثيق محرك تطبيقات جوجل عبر صفحته الرسمية. لابد من الإشارة إلى إمكانية استضافة المواقع على جيت هاب مستخدمًا اسم النطاق الذي تريده، كما يمكنك الاطلاع على معلومات أكثر عن الموضوع من خلال ملفات المساعدة الإلكترونية الخاصة بموقع جيت هاب. ترجمة -وبتصرف- للمقالات التالية: ?How do you upload your files to a web server. ?How do I use GitHub Pages. ?How do you host your website on Google App Engine. اقرأ أيضًا مساعدة المبتدئين في فهم كيفية رفع الموقع على الإنترنت مدخل إلى أسماء النطاقات في شبكة الإنترنت الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث المدخل الشامل لتعلم تطوير الويب
-
لا تستهن بالتفكير التصميمي Design thinking، فقد يغير مسار شركات ومنظمات وحتى حياة الأشخاص، لكنه قد يسبب في انهيار كل شيء إن مارسناه بطريقة سطحية أو دون فهم عميق لأسسه. ستقابل مصطلح "التفكير التصميمي" في كل مكان، وهذا ما يجعل استخدامه وفهمه محفوفًا بالمخاطر. لكن إن كنت على دراية بالعقلية التي يفكر بها المصممون، فلن تخطئ معنى التفكير التصميمي وستجني ثماره بكل تأكيد. تتضمن عقلية المصمم Designer's mindset مجموعة أدوات مثل التعاطف والخيال والغموض والتكرارية والإبداع وحل المشاكل. ويُعَد حال الفكر مشابهًا لحال المصمم، فقد يفشل مبكرًا، وغالبًا ما يتعلّم من أخطائه ويبدأ من جديد مهما استغرق الأمر. إذًا لا بد أن يكون المصمم متفائًلا عندما يجرب أفكارًا جديدةً، وأن يكون قادرًا على الاستفادة من هذه الأفكار، وعندها فقط قد تبصر الحلول التي تختمر في مخيلته النور لتُقيّم وتُجرّب. وهكذا، نرى أن التفكير التصميمي هو توازن مثالي بين التحليل والخيال. ما ستكتشفه لاحقًا، هو أنّ التفكير التصميمي يحمل أبعادًا أوسع من كونه مصطلحًا محيّرًا، وستلمس أهمية النقاط الثمانية التي نستعرضها في مقالنا إن أردت إتقان التفكير التصميمي وتطبيق مبادئه في أعمالك وفي حياتك اليومية أيضًا. 1. تقبل حقيقة أن التفكير التصميمي لا يحدده تعريف معين على الرغم من عدم وجود تعريف محدد للتفكير التصميمي، لكنك ستتمكن من استيعاب التفسيرات المختلفة للمصطلح والطريقة التي تُطبق بها عندما تمتلك معرفة جيدة بعقلية المصمم وأدواتها. لا تعريف محدد للتفكير التصميمي، لكن التفسيرات المختلفة للمصطلح تعتمد المبادئ نفسها طوّرت الشركات والمصممون أساليبهم الخاصة في التفكير التصميمي وكيّفوها لتلبي احتياجاتهم. لنلقِ نظرةً على التعريف الذي تبناه المدير التنفيذي لشركة IDEO "تيم براون" للتفكير التصميمي: إنّ التفكير التصميمي كما تقدّمه IDEO هو أسلوب لاستشعار العالم وحل المشاكل من خلال الإبداع. مع ذلك ستجد في أيامنا هذه تنوّعًا كبيرًا في إطارات العمل التي تُعنى بالتفكير التصميمي وتقديمه بطريقة بصرية، ويضم كل إطار ما بين ثلاث إلى سبع مراحل مستقلة، لكنها جميعًا تعتمد على المبادئ ذاتها. فما تفعله خلال التفكير التصميمي سيتضمن: مقاربة المشكلة بشيء من التعاطف: فلا بدّ لفريق التفكير التصميمي أن يضع حاجة المستخدم في مركز العملية. إعادة صياغة المشكلة أو التحدي مرارًا: لا بد لفريق التفكير التصميمي أن يعيد تحديد المشكلة أو التحدي مرارًا حتى يقف على السبب الجذري للمشكلة. استخدام أنماط تفكير متشعبة في البداية: فالنوعية تأتي من الكثرة في حالتنا. استخدام أنماط تفكير متقاربة في النهاية: يختار الفريق الفكرة التي سيعمل عليها من بين الأفكار التي حصلوا عليها. بناء واختبار نماذج أولية: يطوّر الفريق نموذجًا أوليًا لنقل الأفكار إلى أشياء ملموسة يمكن اختبارها. التكرار: يمكن للفريق تكرار جميع المراحل السابقة وبأي ترتيب وفي أي وقت لتحسين نتائج العمل. 2. التفكير التصميمي ليس حكرًا على المصممين قد تستخدم أي منظمة أو أي فرد مهما كان مجال عمله التفكير التصميمي إن كان المطلوب مقاربةً فعالةً لدفع عجلة الابتكار التي تجعل حاجات الناس مركز عملية التطوير. وقد اعتمدت طرائق التفكير التصميمي واستراتيجياته في عالم الأعمال وعلى مختلف مستوياته. لقد ازدادت شعبية التفكير التصميمي خلال العقود الماضية لأنه كان سببًا رئيسيًا في نجاح العديد من الشركات العالمية المرموقة. وتدرّس الآن طريقة التفكير المنفتحة هذه في الكثير من الجامعات المشهورة، كما يُشجّع على استخدامها في عالم الأعمال وعلى مختلف المستويات. وتجدر الإشارة إلى ضرورة العمل مع فريق متعاون ومتعدد الاختصاصات، يضم أشخاصًا من خلفيات ومهارات مختلفة. بيل جيلبرت، مؤسس شريك في فريق IBM للتفكير التصميمي لقد تبنى العديد من الأشخاص الذي تعلّموا مبادئ التفكير التصميمي أساليبه في حل مشاكلهم، وللحصول على نتائج أو منتجات أفضل. وعلى الرغم من سهولة انخراط المتعلمين الجدد في مسارات التفكير التصميمي، إلا أنّ احترافه سيتطلب أساسًا معرفيًا قويًا والكثير من الوقت والتدريب. ولا ينطبق ذلك على المستويات الفردية فحسب، بل على مستوى المنظمات أيضًا. ولا بد من اعتناق مبادئ التفكير التصميمي في ثقافة المؤسسة حتى يحقق النجاح بما في ذلك تقبل الإخفاق كجزء أساسي من عملية التعلّم وتقبل المجازفة. 3. يبدأ كل شيء عند تحديد المشكلة الحقيقية يبدأ أي مشروع عادة بمشكلة ينبغي حلها، وستكون الخطوة الأولى لنجاح التفكير التصميمي هي إعادة النظر في الافتراضات التي قُدمّت إليك في موجز المشروع كي تتأكد من وقوفك على المشكلة الحقيقية. يميل البشر إلى الاهتمام بالأعراض دون الاهتمام بالمسبب أو المشكلة الجذرية. تخيل أنك توجهت إلى الطبيب لأنك تعاني من الغثيان؛ قد تكون هناك العديد من الأسباب التي تقود إلى الغثيان ابتداءً من التسمم الغذائي وانتهاءً بالحمل. ولكي يعالج الطبيب حالتك بالشكل الصحيح لا بدّ له من إيجاد المسبب الذي لن تتمكن أنت من تحديده لأنك لست متمرسًا في ذلك مثل الطبيب؛ فما تختبره أنت من أعراض يساعد الطبيب بناءً على خبرته في تحديد السبب الكامن خلفها، ثم يصف لك العلاج وفقًا لذلك. وهذا ما عليك فعله كمصمم، إذ عليك إيجاد المشكلة الحقيقية التي يريد العميل حلها. إن تبني هذه المقاربة هو ما سيميزك عن أقرانك في العمل وينقلك إلى مستوى أكثر تقدمًا. اجعل من عملية الاستكشاف صديقك المقرّب، فليس من السهل إيجاد الأسباب الحقيقية للمشكلة مباشرةً حتى على المصمم ولا يعود سبب ضبابيتها إلى معلومات خاطئة قد تحصل عليها من الآخرين عمدًا أو من غير قصد، لهذا عليك استخدام كل أدواتك للوقوف على المشكلة الجذرية، ابتداءً باستطلاعات الرأي والاستبيانات، وصولًا إلى تتبع الأسباب بنفسك ومعاكسة قرارتك وقرارات زملائك وافتراضاتكم. وتذكر دائمًا هذه القاعدة الذهبية: "اكتشف حقيقة ما يقصده العملاء والمستخدمون". وعندها ستكون قادرًا على حل المشكلة الحقيقية. لن يكون الطريق إلى حل المشكلة مستقيمًا، لذا كن مستعدًا للعودة مرارًا وتكرارًا، وشعِّب البحث، مع تحديد صيغ مختلفة للمشكلة، وحاول تكرار البحث واختبار الأفكار. قد يختلف ما نشير إليه عن الأفكار التي تبناها الآخرون مسبقًا عن عملية إيجاد المشكلة الحقيقية، والتي قد تبدو عمليةً مباشرةً لا تشعبات فيها، مثل خط مستقيم من المشكلة A إلى الحل B، فالحقيقة هي أن الطريق سيبدو نوعًا ما كما في الشكل التالي: "عملية التصميم ليست خطًا مستقيمًا، بل هي عملية متشعبة لا بدّ من خوضها لتتضح الأمور" وبمجرد أن ترتاح إلى هذا التمثيل المجازي الذي يعبّر عن عملية التفكير التصميمي بأفضل حالاته، فسيخف شعورك بالغضب وستنجز عملك بجودة أكبر. قد يكون من الصعب نقل هذه الأفكار إلى الثقافة التقليدية للكثير من المنظمات، لكن عدّ نفسك سفيرًا للتفكير التصميمي ضمنها. 4. تقبل الطبيعة الكسيرية لعملية التفكير التصميمي لنتأمل أحد أكثر أطر عمل التفكير التصميمي شعبيةً، والذي صاغته مدرسة "ستانفورد" على أنه عملية لاخطية قابلة للتكرار وتتألف من خمس مراحل هي: التعاطف (تخيل نفسك مكان العميل). تعريف المشكلة. وضع تصورات لها. وضع نماذج أولية. الاختبار. تبدو المراحل مثل خط مستقيم أليس كذلك؟ إذ تكمن المشكلة الحقيقية في فهم وتنفيذ هذه المراحل بتتابع لاخطّي وبأسلوب تكراري، فقد تكون هاتين المفردتين هما الوصفة السرية لنجاح التفكير التصميمي. يتصوّر معظم البشر الزمن على شكل مسار مستقيم إلى حد ما، ولهذا نفضل العمليات المرتبة التي تتجه إلى الأمام مباشرةً أو إلى الخلف مباشرةً، وبإرشادات واضحة كي لا نضيع. توقّف لبرهة وتأكد من فهمك أو عدم فهمك لأهمية اللاخطية والتكرارية. تخيل الأمر مثل عنصر كُسيري fractal، ودعنا نَعُد الكُسيريات في مجالنا على أنها أنماط تتكرر إلى ما لانهاية. ما الذي سيحدث لو فكّرت بالمراحل الخمسة السابقة كأنماط تتكرر إلى ما لا نهاية؟ سيعني ذلك أن كل مرحلة ستتضمن المراحل الخمسة ذاتها وهكذا. فإن استوعبت وتقبلت مرونة التفكير التصميمي واستطعت رؤيته مثل عملية مستمرة، فستحصد نتائج أفضل وتستمتع بما تفعل، إذ سيتطور النموذج الأولي الذي تبنيه على سبيل المثال مع كل تكرار، وذلك ابتداءً بالرسم الأولي البسيط إلى النسخة الرقمية الكاملة الجاهزة للاختبار. سيتطور أيضًا تحديدك للمشكلة، وقد يختلف الأمر تمامًا في النهاية؛ ولا بد إذًا من إتقان لعبة التقارب والتباعد عن المشكلة لتحترف التفكير التصميمي، لكن إن كانت العملية لا متناهية، فكيف سنقدم الحل النهائي؟ وكيف سينتهي الأمر؟ 5. تعلم متى تنهي عملية التفكير التصميمي إليك الحقيقة المُرّة: يبدو أن النتائج لا تظهر عادةً إلا قبل 24 ساعة من الموعد النهائي للتسليم، أيًا كان الوقت المتاح أمام المصمم كي ينجز تصميمه. هذه هي طبيعة العملية، فلن تصل إلى مرحلة الكمال أبدًا، لكن كلما كررت العملية أكثر، ستقترب من الإتقان. ويتطلب الأمر قائدًا خبيرًا للفريق ليقرر أنّ حلًا ما هو الأفضل، وذلك بناءً على ميزانية المشروع والوقت المتاح. ولكي تبدأ بتنفيذ عملية التفكير التصميمي بالأسلوب الصحيح، لا بد أن تتأكد أولًا من إمكانية تطبيق هذه العملية، فلن يكون الحل جيدًا إن لم يعتمد على الموارد المتوفرة. وحتى لو تمكنت من بناء الحل، فلن يُنتج مردودًا كافيًا للعمل، كما لن يكون حلًا مستدامًا قابلًا للتجديد. مع تنامي خبراتك، ستتعلم متى تنتقل من عملية التفكير التصميمي إلى عملية تطوير المُنتج، ومع ذلك لن تنتهي عملية التفكير التصميمي بإطلاق منتجك أو الحل الذي تعمل عليه، فقد تتابع البحث والاطلاع لتحسين حلولك ومنتجاتك باستمرار. إن أحد جوانب المتعة في المنتجات الرقمية، هي الإضافات المستمرة لتحسين تجارب مستخدميك حتى بعد حصولهم على منتجاتك. 6. يتعارض التفكير التصميمي مع التحيز البشري يتميز التفكير التصميمي بأنه منهجية أساسية ينبغي استعمالها بحكمة. وما يجعل التفكير التصميمي أحد الأدوات الأساسية في الإبداع الذي يستند إلى الحاجة البشرية، هو تعارضه مع التحيز البشري الصريح أو المخفي تحت الرغبات اللاواعية، فإن أدركت هذه الحقيقة، فعندها ستمتلك ناصية هذه المنهجية وستضع نفسك في مكان مرموق لتقديم أفضل النتائج. نتعلم -بصفتنا بشر- من تجاربنا الماضية. ومن أنماط محددة من التفكير، قد لا ندرك في الواقع أننا نتبناها. وما يحتاجه الابتكار كما ندرك جميعًا تفكيرًا منفتحًا، فلا بدّ إذًا من كسر تلك الأفكار التي تبنيناها مسبقًا كي ننجز تلك الابتكارات. وبكلمات أخرى، لا بد من التخلص من الأحكام المسبقة. سيمنحك التفكير التصميمي إطار عمل يساعدك في تجاوز تلك العقبات ضمن بيئة تعاونية مريحة. إنّ البعد التعاوني هو ما يمنح التفكير التصميمي القوة الحقيقية، وهو الوصفة السرية للابتكار الذي يجعل الحاجات البشرية مركز اهتمامه. لا تعتقد أبدًا أن التفكير التصميمي عملية مريحة وخالية من التعب، فهي ستدفعك وفريقك لإيجاد أفضل الحلول وليس أسهلها. ومن زاوية فلسفية، هي أسلوب يدفعك إلى تحدي أفكارك ذاتها وتقييم كل خطوة في مسيرة عملك لتصل في النهاية إلى ابتكار قد يغير العالم. 7. يهيئ لك التفكير التصميمي إطارا لعملية الابتكار لقد أصبح التفكير التصميمي المقاربة المشتركة في جميع الابتكارات التي تتمحور حول حاجات الناس، ويُعَد الابتكار هو المنتج الرئيسي. نعيش جميعًا في عالم لا شيء ثابت فيه سوى "التغيير"، ووفق هذه الرؤية، سيكون الابتكار جوهريًا لمعالجة التحديات الجديدة التي تواجه المجتمع. فكّر في طفولتك، ما الذي احتجته حينها؟ هل لا زلت تحتاج تلك الأشياء الآن؟ على الأرجح لا، فقد ساعدتك تجاربك خلال مسيرة حياتك في تعلم مهارات جديدة لتخطي العقبات الجديدة، وقد يحدد الاكتفاء الذاتي الذي تشعر به قدرتك على تجاوز هذه العقبات بنجاح. يمكننا توسيع هذا المنطق إلى مجالات أوسع، فبصفتنا مجتمعًا، سنحتاج إلى الابتكار للتغلب على التحديات الطارئة، مثل الشيخوخة والنمو السكاني وتغيرات المناخ وهكذا، لذا لا بدّ أن نبتكر لنبقى. يساعدنا التفكيرالتصميمي على الابتكار، ولهذا السبب لا بدّ من أن نبدي جدية أكثر في تعميمه. يمثّل الشكل السابق منحنيًا بيانيًا يشير إلى تفوق بعض الشركات التي اعتمدت التفكير التصميمي مثل آبل ووالت ديزني وغيرها بمقدار 219% موازنةً مع غيرها من الشركات الخمسمائة الكبرى وفق تصنيف ستاندرد آند بورز S&P 500، فقد تقدّمت الشركات والمنظمات التي طبقت مقاربة التفكير التصميمي بالشكل الصحيح في عالم الابتكار كما تأقلمت مع العالم المتغير الذي يحيط بنا وبقيت محافظةً على مكانتها. وتحاول هذه الشركات تكرار منتجاتها وتحسينها أكثر فأكثر للتأكد من تحقيق حاجات مستخدميها باستمرار 8. يتطلب التفكير التصميمي وقتا لإتقانه لا يمكن تعلم التفكير التصميمي بين يوم وليلة، وهذا أمر طبيعي. ومن المحتمل أنك تابعت العديد من ورشات عمل ليوم واحد تتحدث عن التفكير التصميمي وهي بلا شك بداية تعريفية ممتازة، لكن تذكر دومًا أن التفكير التصميمي يتطلب وقتًا وجهدًا. فقد تتدرب ليوم كامل مثلًا على الجري، لكن لا تتوقع أن تربح مارثونًا بعدها مباشرةً، خاصةً إذا كنت بدون خبرة سابقة. وهذا ما يحدث تمامًا مع التفكير التصميمي الذي قد يستغرق وقتًا أطول حتى في إتقان منهجيته. لا ينحصر التفكير التصميمي بفئة المصممين، وقد يسيء المبتدئون استخدامه لأنه منهجية تُتقن بالمران. لذلك خذ وقتًا كافيًا لفهم حقيقة التفكير التصميمي، وأسباب استخدامه، والغاية منه؛ وهكذا ستكون قادرًا على تقديم إضافات جديدة للعملية عندما تقدم وجهة نظرك وتصل إلى حلول ناجحة. ترجمة وبتصرف للمقال: 8 Must-Know Insights to Conquer Design Thinking لصاحبته Laia Tremosa. اقرأ أيضًا المرحلة الأولى من عملية التفكير التصميمي: التعاطف مع المستخدمين المرحلة الثالثة في عملية التفكير التصميمي: مرحلة التفكير المرحلة الرابعة في عملية التفكير التصميمي: مرحلة بناء النماذج الأولية استخدام التفكير التصميمي لتخطي مشاكل رائد الأعمال
-
يصف المقال طريقة إعداد خادم اختبار محلي على حاسوبك وكيفية استخدامه، كما ننصحك بدايةً بالاطلاع على كيفية عمل الإنترنت والتعرُّف على خادم الويب. الملفات على الخادم المحلي موازنة بالملفات على خادم بعيد يمكنك بكل بساطة فتح ملف HTML أو صفحة ويب على حاسوبك بالنقر المزدوج عليه، أو من خلال سحبه ثم إفلاته داخل المتصفح، أو من خلال قائمة ملف File ثم فتح Open، ومن ثم الانتقال إلى الملف المطلوب، ولاحظ أنّ أيّ ملف موجود على القرص الصلب لحاسوبك سيبدأ عنوانه بالشكل //:file يلي ذلك مسار الملف، بينما إذا استعرضت ملفًا على جيت هاب GitHub أو على أيّ خادم آخر، فستلاحظ بدء عنوانه بـ //:http أو //:https للدلالة على حصولنا عليه عبر بروتوكول HTTP. مشكلة اختبار الملفات المحلية لن تتمكن من فتح بعض الأمثلة إذا عاملتها على أنها ملفات محلية، إذ يعود ذلك إلى أسباب مختلفة أهمها: قد تمثل هذه الملفات ردودًا لطلبات غير متزامنة asynchronous requests: لن تنفِّذ بعض المتصفحات -بما فيها جوجل كروم- الطلبات غير المتزامنة إذا جرى طلبها عن طريق ملف محلي لأسباب تتعلق بقيود أمنية. قد تستخدم هذه الملفات شيفرة لغات تعمل على الخادم: مثل PHP أو بايثون، والتي تتطلب خوادم خاصة لتفسير الشيفرة وإيصال النتائج. تعامل المتصفحات الطلبات التي تحمِّل موارد محلية عبر بروتوكول file:// على أنها طلبات ذات أصل مختلط cross-origin requests، لذا إن حمَّلت ملفًأ محليًا يحوي يطلب ملفات محلية أخرى، فقد يولد هذا خطأ CORS (اختصارٌ إلى سياسة مشاركة الموارد ذات الأصول المختلطة). تشغيل خادم HTTP محلي بسيط لا بدّ من اختبار الأمثلة المشابهة على خادم ويب محلي لتجاوز مشكلة الطلبات غير المتزامنة، إذ سيكون استخدام وحدة خادم HTTP لبايثون http.server من أسهل طرق تنفيذ ذلك. اتبع الخطوات التالية لإعداد الخادم: ثبِّت بايثون: من المفترض أن تكون حزمة بايثون مثبتةً على جهازك مسبقًا إذا كنت تستخدِم لينوكس Linux أو ماك أو إس macOS، بينما إذا كنت تستخدِم ويندوز Windows، فعليك زيارة الصفحة الرسمية لبايثون والحصول على المُثبِّت الخاص بويندوز من خلال الخطوات التالية: انتقل إلى العنوان python.org. انقر على الرابط "Python "3.xxx الموجود ضمن قسم التنزيل Download. انقر على رابط مُثبِِّت ويندوز Windows Installer الموجود أسفل الصفحة لتنزيل ملف التثبيت. شغّل ملف التثبيت عند انتهاء التنزيل. تأكد من تفعيل مربع التحقق الذي يشير إلى إضافة بايثون إلى المسار Add Python 3.xxx to PATH. انقر على تثبيت Install، ثم انقر على إغلاق Close عند انتهاء العملية. افتح موجه سطر الأوامر Command Prompt في ويندوز أو الطرفية Terminal في لينوكس أو ماك لتتحقق من تثبيت بايثون. نفذ الأمر التالي: python -V # إن فشلت التعليمة السابقة استخدم التعليمة python3 -V # إن كان متاحًا "py" أو حاول استخدام الأمر py -V سيعيد إليك الأمر السابق رقم إصدار بايثون الذي ثُبِّت، ثم انتقل بعد ذلك إلى المجلد الذي يحتوي على المثال الذي تريد اختباره باستخدام الأمر cd إذا كان المثال على سطح المكتب أو في مكان آخر، فجرّب الانتقال إليه وفق أحد الأسلوبين التاليين: # ضع عنوان المجلد الذي يحوي المثال الذي تريد اختباره cd Desktop # استخدم النقطتين للانتقال إلى مجلد أعلى بمستوى واحد cd .. استخدم الأمر التالي لتشغيل الخادم ضمن المجلد المحدد: # إذا كان إصدار بايثون 3 # حاول ما يلي على ويندوز # "python -m http.server" # أو # "py -3 -m http.server" python3 -m http.server # إذا كان إصدار بايثون 2 python -m SimpleHTTPServer ستنفِّذ التعليمة السابقة محتوى المجلد على خادم ويب محلي ورقم المنفذ الخاص به 8000، كما يمكن الوصول إلى هذا الخادم من خلال كتابة العنوان localhost:8000 ضمن المتصفح الذي سيعرض لك محتويات المجلد، وانقر على ملف HTML الذي تريد تشغيله. # بايثون 3 python3 -m http.server 7800 # بايثون 2 python -m SimpleHTTPServer 7800 ستتمكن من الوصول إلى الخادم على هذا المنفذ بكتابة العنوان localhost:7800 ضمن المتصفح. تنفيذ شيفرة لغة تعمل على الخادم لن تستطيع وحدتَي بايثون http.server أو SimpleHTTPServer التي تعمل على الإصدار 2 على الرغم من فائدتهما من تنفيذ شيفرة مكتوبة بلغات مثل بايثون أو PHP أو جافاسكربت، فهي تقدِّم بالكاد خادم ملفات ساكن static file server، ولتنفيذ شيفرات مثل هذه، فلا بدّ من عمل إضافي يتعلق بطبيعة اللغة التي تستخدِمها، وإليك بعض الأمثلة: لتنفيذ شيفرة بايثون، لا بدّ من استخدام إطار عمل بايثون خاص بالويب Python web framework، وستجد الكثير من إطارات العمل هذه مثل Django أو Flask أو Pyramid. لتنفيذ شيفرة Node.js -جافاسكربت-، لا بدّ من استخدام Node الأساسي أو أيّ إطار عمل مبني على أساسه مثل إكسبرس Express الذي يمثِّل خيارًا جيدًا. لتنفيذ شيفرة PHP، شغّل خادم PHP المدمج كما يلي: $ cd path/to/your/php/code $ php -S localhost:8000 ترجمة -وبتصرف- للمقال ?How do you set up a local testing server. اقرأ أيضًا دليل إعداد خادم ويب محلي خطوة بخطوة الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث
-
يختلف أثر رسوم CSS المتحركة الناتجة عن التغيير التدريجي لخصائص التنسيق من خاصية إلى أخرى، وقد تؤدي عمليات التحريك المكثفة إلى جمود المتصفح وهو يحاول تحقيق معدل إطارات مناسب لعرض أكثر نعومةً، كما تساعدك الأداتين Frame rate وWaterfall في الإضاءة على عمل المتصفح أثناء تنفيذه هذه الرسوميات لتشخيص مشاكل الأداء التي تنتج عنها. تحدِّد عدد الإطارات عندما تستخدِم رسوم CSS المتحركة، إذ تستخدِم CSS كل إطار لتعريف مظهر العنصر خلال مراحل الحركة، ويعرض المتصفح الحركة بالانتقال من إطار إلى آخر، كما تُعَدّ رسوميات CSS المتحركة أسهل تنفيذًا من رسوميات جافاسكربت، كما تقدم أداءً أفضل أيضًا، وذلك لأنها تمنح المتصفح قدرًا أكبر من التحكم بتوقيت تصيير الإطارات، وإمكانية تجاوز بعضها إذا كان ذلك ضروريًا. يختلف تأثير التعديلات التي نُحدثها على خصائص CSS تبعًا للخاصية المستهدفة. فتحريك العناصر باستخدام خصائص تستهلك موارد أعلى، سيفضي إلى عرقلة أداء المتصفح الذي يحاول جاهدًا بلوغ معدل إطارات مرتفع. تسلسل تصيير رسوميات CSS يُحدِّث المتصفح صفحة ويب عندما تتغير خاصية CSS عبر عملية متسلسلة تتضمن الخطوات التالية: إعادة ضبط التنسيق Recalculating Style: لا بدّ للمتصفح من إعادة ضبط التنسيق في كل مرة تتغير فيها خاصية CSS لعنصر. تخطيط الصفحة Layout: يستخدِم المتصفح التنسيق الجديد في الخطوة الثانية لضبط موقع وهندسة العنصر، وتدعى هذه المرحلة تخطيط الصفحة أو إعادة الانسياب reflow. رسم الصفحة Paint: لا بدّ للمتصفح في النهاية من إعادة رسم العناصر على الشاشة، ولم نعرض في التسلسل السابق خطوةً أخيرةً تقتضي بتقسيم الصفحة أحيانًا إلى طبقات يُعاد رسمها بصورة مستقلة، ثم تُدمج مجددًا بعملية تدعى التركيب Composition. لا بدّ من اتساع إطار واحد للتسلسل السابق طالما أنّ الشاشة لن تُحدِّث حتى اكتمال سلسلة التنفيذ السابقة، ومن المعروف أنّ معدل 60 إطار في الثانية كافٍ لإظهار الرسوميات المتحركة بصورة سلسة وناعمة على الشاشة، ويتطلب هذا من المتصفح تنفيذ السلسلة السابقة خلال 16.7 ميلي ثانية. تأثير الخاصية على الأداء يؤثر تحريك بعض خاصيات CSS أكثر من غيرها على أداء صفحة الويب إليك بعض الأمثلة: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } نوع الخاصية Cost مثال ستتسبب الخصائص التي تتحكم تغيراتها بموقع وهندسة العنصر في وقوع أحداث إعادة ضبط التنسيق وتخطيط الصفحة وإعادة رسمها left max-width border-width margin-left font-size لن تتسبب الخصائص التي لا تتحكم تغيراتها بموقع وهندسة العنصر ولا تُصيّر في طبقة مستقلة في وقوع حدث تخطيط الصفحة. color لا تتسبب الخصائص التي تُصيّر في طبقة مستقلة في وقوع حدث إعادة الرسم أيضًا، لأن تحديث الصفحة سيُنفَّذ في خطوة التركيب.. transform opacity يمكنك الاطلاع على تأثير كل خاصية من خاصيات CSS على ملف الأداء وفقًا للمتصفح المستخدَم عبر الموقع CSS Triggers. مثال تطبيقي: موازنة بين أثر الخاصيتين margin وtransform سترى خلال هذه الفقرة كيف تشير الأداة إلى الفرق بين تحريك الكائنات من خلال الخاصية margin والخاصية transform، كما لا يهدف هذا السيناريو إلى إقناعك بأنّ استخدام الخاصية فكرة سيئة دومًا، وإنما لتوضيح فائدة أدوات تحليل الأداء في الإضاءة على عمل المتصفح أثناء تصيير موقعك وكيفية استخدام هذه الإضاءات لتشخيص وتصحيح مشاكل الأداء، فإذا أردت تجريب الأمر، فانتقل إلى صفحة المثال التطبيقي، والتي تبدو بالشكل التالي: تملك الصفحة أداتَي تحكم: زر تشغيل/ توقف: لتشغيل وإيقاف تشغيل الحركة. مجموعة أزرار اختيار: لاختيار أسلوب الحركة باستخدام transform أو margin. ستجد في الصفحة مجموعةً من العناصر أضفنا لها خلفيةً بألوان متدرجة باستخدام الخاصية linear-gradient وظلال حولها بتطبيق الخاصية shadow لأنّ كلتا الخاصيتين السابقتين شديدتا التأثير على الأداء. تحريك العناصر باستخدام margin ابقي الخيار على Use margin وابدأ الحركة، ثم افتح الأداة Performance وأنشئ تسجيلًا جديدًا، فليس عليك في الواقع سوى تسجيل بضعة ثوان. افتح التسجيل الأول، إذ سيعتمد ما تراه على حاسوبك وحمولة نظام التشغيل، لكنه سيبدو قريبًا من الشكل التالي: تظهر في الشكل ثلاثة مشاهد مختلفة: (a): نظرة عامة للأداة Waterfall. (b): معدل الإطارات. (c): تفاصيل الشريط الزمني. نظرة عامة للأداة Waterfall تُظهِر اللوحة مشهدًا مضغوطًا للأداة Waterfall يسيطر عليه اللون الأخضر الذي يوحي بقضاء المتصفح معظم وقته في عمليات الرسم. معدل الإطارات يُظهِر الشكل السابق معدّل الإطارات الذي يشير إلى وسطي قدره 46.67 إطار في الثانية، وهو أقل من المعدل المستهدَف البالغ 60 إطار في الثانية، والأسوأ من ذلك التعرجات الشديدة والانخفاضات المتكررة التي تصل بالوسطي إلى العشرينات والعشرات، فمن غير المحتمل رؤية حركة ناعمة في هذه الحالة وخاصةً عندما تضيف إليها العمليات الناتجة عن تفاعل المستخدِم مع الصفحة. تفاصيل الأداة Waterfall يعرض باقي التسجيل تفاصيل الأداة Waterfall، فإذا تنقَّلت خلال التفاصيل، فستجد نمطًا متكررًا كما يلي: يُظهِر الشكل السابق تسلسل عملية تصير الصفحة، إذ يُعاد ضبط تنسيق كل عناصر الصفحة في كل إطار، ثم تجري عملية تخطيط واحدة للصفحة، ومن ثم إعادة رسم الصفحة، إذ تُخفّض عملية الرسم كما تلاحظ من أداء الصفحة. سلطنا الضوء في لقطة الشاشة السابقة على عملية رسم، إذ يخبرنا امتدادها أنها استغرقت 13.11 ميلي ثانية من أصل 16.7 ثانية وهو زمن تنفيذ عمليات الإطار بكاملها إذا أردنا أداءً سلسًا وناعمًا، وهذا هو السبب وراء انخفاض معدل الإطارات وعدم استقراره، كما من الممكن تعديل الاختبار بإزالة الظلال حول العناصر، ومن ثم ترى أثر ذلك على الأداء، وسنحاول تاليًا استخدام الخاصية transform بدلًا من margin وسنرى النتيجة. تحريك العناصر باستخدام الخاصية transform اختر الآن زر Use transform ضمن خيارات التشغيل في صفحة المثال التطبيقي السابقة وأنشئ تسجيلًا ثانيًا، إذ سيبدو شكل لوحة النظرة العامة للأداة Performance كما يلي: نظرة عامة للأداة Waterfall لاحظ وجود علامات خضراء أقل بكثير من المشهد نفسه عند استخدام الخاصية margin والكثير من اللون الزهري، والذي يوحي بعمليات تخطيط كثيرة أو عمليات إعادة ضبط تنسيق الصفحة كثيرة. معدل الإطارات Frame Rate يبدو الوضع أفضل موازنةً مع الحالة السابقة، فقد حققت الصفحة معدلًا قريبًا من 60 إطار في الثانية، كما يبدو معدل الإطارات في تزايد مستمر بغض النظر عن الانخفاض الملموس في معدل الإطارات في البداية. تفاصيل الأداة Waterfall تدل التفاصيل على سبب التحسن في معدل الإطارات موازنةً بالحالة السابقة، إذ لا يقضي المتصفح وقتًا طويًلا في تخطيط الصفحة أو في عملية الرسم وهي الناحية الأهم في حالتنا. حسَّن استخدام الخاصية transform أداء الموقع بصورة واضحة، وقد أرشدتنا الأداة Performance إلى طبيعة التحسن وسببه. ترجمة -وبتصرف للمقال Animating CSS Properties. اقرأ أيضًا المرجع الشامل إلى التحريك عبر CSS أساسيات التحريك: إنشاء صفحات ويب تفاعلية متجاوبة المكونات الرئيسية للأداة Performance لتحليل أداء صفحات الويب التحريك عبر CSS
-
إن كنت نشرت موقعك الإلكتروني وأصبح متاحًا للجميع، فهل أنت على ثقة بأن كل شيء يجري على ما يرام؟ سنناقش في هذا المقال عدة خطوات قد تتبعها لتتأكد من عمل موقعك، وبعض الإجراءات التي يمكن اتخاذها لتلافي بعض المشاكل التي تظهر. يملك خادم الويب البعيد سلوكًا قد يختلف أحيانًا عن سلوك الخادم المحلي الذي اختبرت عليه موقعك، لهذا من الأفضل اختبار الموقع عند نشره على الويب مباشرةً، وقد تفاجئك كمية المشاكل التي قد تظهر مثل الصور الغير معروضة أو الصفحات الغير محمَّلة أو التي تعاني بطأً في التحميل وغيرها، لكنك ستجد لحسن الحظ أنّ معظم هذه المشاكل ليست بتلك الخطورة، وإنما هي أخطاء بسيطة أو بعض الإشكالات في إعدادات الخادم الذي يستضيف الموقع. سنطّلع إذًا في مقالنا على الطريقة التي نُشخِّص بها المشاكل التي تعترض موقع الويب إبان نشره وآلية معالجتها، وإليك بعض الاختبارات البسيطة التي لابد من إجرائها فور نشر موقعك على الويب. اختبر الموقع على متصفحك لا بدّ من تشغيل موقعك الإلكتروني من خلال متصفحك فور نشره على الويب كي تتفحص عمله وتتأكد من سير كل شيء كما هو متوقع له. صورة مفقودة لنلق نظرةً على هذه الصفحة الاختبارية من موزيلّا، حيث ستلاحظ عدم وجود صورة يونيكورن unicorn. لنلق نظرةً على الأداة "شبكة الاتصال Network" والتي نصل إليها من خلال: أدوات Tools> أدوات مطوري ويب Web Developers> شبكة الاتصال Network. سنجد أنّ المشكلة في الخطأ "404" والذي يشير إلى أنّ المورد المطلوب غير موجود، وبالتالي لن يعرِض المتصفح الصورة. حالات HTTP يستجيب الخادم برسالة توضِّح حالة الطلب في كل مرة يتلقى طلبًا، وإليك أكثر الرسائل شيوعًا: 200 (موجود OK): المورد الذي تطلبه قد أرسل إليك بنجاح. 301 (نُقل نهائيًا Moved Permanently): بمعنى أنه قد نُقل المورد إلى مكان آخر، ولن يعرِض متصفحك هذه الرسالة كثيرًا، لكن من المفيد الاطلاع على فحواها، وذلك لأنّ محركات البحث تستخدمها بكثرة من أجل تحديث فهارسها. 304 (لم يتغير Not modified): لم تطرأ أية تعديلات على المورد منذ آخر مرة طلبته فيها، وبالتالي سيتمكن المتصفح من عرض النسخة التي يحتفظ بها في ذاكرته المؤقتة cache، مما يزيد من سرعة الاستجابة وفعالية استخدام نطاق حزمة التراسل المخصصة. 403 (ممنوع Forbidden): لا يُسمح لك بالوصول إلى المَورد، وعادةً ما يكون السبب خطأً في الإعدادات، إذ يغفل المضيف عن إعطائك أذونات الوصول إلى المَورد على سبيل المثال. 404 (غير موجود Not found): تشرح الحالة نفسها بنفسها وسنناقش حلها لاحقًا. 500 (خطأ داخلي في الخادم Internal Server Error): قد تتوقف أحد لغات البرمجة التي تعمل على الخادم مثل PHP أو Net. عن العمل عندما تحدث مشكلة في الخادم، كما قد يعاني خادم ويب من أخطاء في الإعدادات، وبالتالي عليك العودة في هذه الحالة إلى فريق العمل الذي يُشرف على الاستضافة. 503 (الخدمة غير متوفرة Service unavailable): ينتج هذا الخطأ عادةً عن زيادة حمولة مؤقتة على النظام أو حدوث خطأ على الخادم، وبالتالي عليك التجريب مجددًا بعد فترة. سيواجه المبتدئون الذين يتحققون من مواقعهم البسيطة الحالات 200 و304 و403 و404 غالبًا. حل المشكلة 404 ما الخطأ الذي حدث؟ تبدو الصورة التي نبحث عنها في مكانها للوهلة الأولى، لكن مع ذلك يعيد الخادم الخطأ 404، فإذا دققنا الآن في شيفرة HTML، فسنلاحظ الخطأ المطبعي الذي ارتكبناه في كتابة اسم الصورة unicorn_pics.png بدلًا من unicorn_pic.png، لذا صحِّح الخطأ ضمن السمة src لوسم الصورة لتحل المشكلة. احفظ التغييرات وادفع بالملف المصحَّح إلى الخادم، ثم حمِّل الصفحة من جديد على متصفحك: لنلق نظرةً مجددًا على حالتَي HTTP المعروضتين أسفل الصورة السابقة: 200: الموافقة لطلبَي الإحضار / وunicorn_pic.png، وهذا يعني أننا نجحنا في إعادة تحميل الصفحة وفي عرض الصورة. 304: الموافقة لطلب إحضار الملف basic.css، وتعني عدم تغيّر الملف منذ آخر مرة طُلِب فيها، وبالتالي يمكن للمتصفح استخدام النسخة المحفوظة منه ضمن ذاكرته المؤقتة عوض تلقي نسخة جديدة وهكذا نكون قد أوجدنا حلًا لمشكلتنا وتعلمنا في الوقت نفسه شيئًا مفيدًا عن بعض حالات HTTP. أخطاء تحدث باستمرار إليك أكثر الأخطاء التي نواجهها تكرارًا: أخطاء مطبعية في العناوين إذا أردنا مثلًا كتابة العنوان Http://academy.hsoub.com ونسينا كتابة الحرف "u" بسبب السرعة، فلن يتمكن المتصفح من إيجاد العنوان. الخطأ 404 قد ينتج الخطأ أحيانًا عن خطأ مطبعي، لكنه ينتج في أحيان أخرى عن نسيان رفع المورد إلى الخادم أو عن فقدان الاتصال أثناء رفعه، لذا تحقق من كتابة وصحة مسار الملف، وارفع الملفات مجددًا إذا استمرت المشكلة، إذ ستحل هذه الإجراءات البسيطة المشكلة غالبًا. أخطاء جافاسكربت أضاف أحد ما -أنت مثلًا- سكربت إلى صفحة ويب وارتكب خطأً، إذ لن يمنع ذلك الخطأ تحميل الصفحة، لكنك ستدرك وجود خطب ما. تعرض لك الصورة السابقة الخطأ الذي ارتكبته بدقة، وبالتالي سيسهل علينا إصلاحه. أمور إضافية ينبغي التحقق منها لقد زودناك ببعض الوسائل البسيطة التي ستساعدك في التحقق من صحة عمل موقعك والأخطاء التي تقع باستمرار وكيفية التعامل معها، كما يمكنك التأكد من تحقيق صفحتك للمعايير التالية: أداء الصفحة هل تُحمّل الصفحة بسرعة كافية؟ قد تساعدك بعض الموارد مثل WebPageTest.org أو بعض إضافات المتصفح مثل YSlow في فهم بعض أمور مهمة مثل هذه. لاحظ كيف تصنِّف YSlow الصفحات من الدرجة A حتى F، فقد حققت الصفحة البسيطة في مثالنا معظم معايير الأداء، لذلك صنفت على أنها من الدرجة A مع ملاحظة ضرورة استخدام شبكة تسليم محتوى Content Deleivery Ntework -أو CDN اختصارًا-، كما لن يكون استخدامها أمرًا ملحًا في صفحتنا التي تعرض صورةً واحدةً، وإنما عندما يقدِّم موقع الويب آلاف الصور ويعاني من زيادة مستمرة في عرض حزمة الاستهلاك. استجابة الخادم يمكن استخدام الأداة ping الموجودة في مفسِّرات الأوامر في اختبار اسم النطاق والتأكد من استجابة الخادم الذي يستضيفه: $ ping mozilla.org PING mozilla.org (63.245.215.20): 56 data bytes 64 bytes from 63.245.215.20: icmp_seq=0 ttl=44 time=148.741 ms 64 bytes from 63.245.215.20: icmp_seq=1 ttl=44 time=148.541 ms 64 bytes from 63.245.215.20: icmp_seq=2 ttl=44 time=148.734 ms 64 bytes from 63.245.215.20: icmp_seq=3 ttl=44 time=147.857 ms ^C --- mozilla.org ping statistics --- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 147.857/148.468/148.741/0.362 ms انتبه إلى إمكانية استخدام الاختصار Ctrl+C من خلال لوحة المفاتيح في مقاطعة عمل الأداة عندما تحصل على المعلومات التي تريد، إذ ستعمل الأداة إلى ما لانهاية إذا لم توقفها. قائمة تحقق بسيطة تحقق من الأخطاء التي تحمل الرقم 404. تحقق من عمل كل صفحات موقعك كما هو مطلوب. استعرض موقعك ضمن عدة متصفحات لتتأكد من تصييره بالصورة الصحيحة. لقد رفعت موقعك وأصبح جاهزًا ليستقبل الزوار، إذ أنجزت خطوةً متقدمةً وعليك الآن التعمق في تفاصيل أكثر. قد يزور موقعك أشخاص من مختلف أرجاء العالم، لذلك عليك التفكير في جعله متاحًا للجميع. هل تعتقد أنّ موقعك يحتاج إلى المزيد من الصقل؟ إذًا عليك تعلم المزيد حول لغة أوراق الأنماط المتتالية CSS. ترجمة -وبتصرف- للمقال ?How do you make sure your website works properly. اقرأ أيضًا كيف تنشر صفحة أو موقع ويب قمت بتصميمه على الإنترنت الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث كيفية التعامل مع الويب المدخل الشامل لتعلم تطوير الويب
-
تتكون الأداة Performance من أربع أدوات جزئية سنشرحها في هذا المقال بشيء من التفصيل. الأداة Waterfall تقدِّم لك هذه الأداة عرضًا للأعمال التي ينفِّذها المتصفح عندما يستعرض موقعك أو تطبيقك، ويعتمد عمل الأداة على فكرة أنّ الأشياء التي ينفذها المتصفح عندما يستعرض موقعًا يمكن تصنيفها ضمن عدة فئات منها تشغيل شيفرة جافاسكربت وتحديث مخطط الصفحة وغيرها، وأنّ ما ينفذه المتصفح في لحظة ما هو شيء واحد فقط، فإذا لاحظت علامةً على مشكلة في الأداء مثل انخفاض عدد إطارات مع الزمن، فيمكنك التوجه إلى الأداة Waterfall لترى ما كان يفعله المتصفح في هذه اللحظة إذا كنت تسجل ملف الأداء. يمثِّل المحور X الزمن المنقضي، كما تظهر العمليات المسجلة التي ندعوها علامات Markers على أساس أشرطة أفقية تتتابع مثل الشلال لتعكس الطبيعة التسلسلية لآلية تنفيذ المتصفح للعمليات، فعندما تختار علامةً ما، فسترى معلومات عنها ضمن الشريط الجانبي الذي يقع على اليمين وتتضمن الفترة الزمنية التي استغرقتها العلامة وغيرها من المعلومات الخاصة بنوع العلامة marker type. العلامات تملك العلامات التي ترتبط بالعمليات المنفذة نظامًا لونيًا محددًا وسنستعرضها في هذا القسم: أحداث DOM: تمثَّل باللون، وهي شيفرة جافاسكربت التي تُنفَّذ على أساس استجابة لأحداث DOM. تقدم هذه العلامات معلومات عن ما يلي: نوع الحدث Event type: مثل نقرة click أو رسالة message. مرحلة الحدث Event Phase: مثل هدف Target أو التقاط Capture. دوال جافاسكربت: تُمثَّل باللون، وهي الدوال التي ينفِّذها المتصفح في صفحة الويب وتُعنون وفقًا للسبب الذي استُدعي التابع لأجله، كما تقدِّم المعلومات على صورة مكدّس استدعاءات call stack مزوَّد بروابط إلى هذه الدوال: Script tag: تتعلق بالتعامل مع وسوم الشيفرة. setInterval: تتعلق بضبط الفترات الزمنية. setTimeout: تتعلق بتحديد زمن انتهاء العملية. requestAnimationFrame: تتعلق بطلبات إطار رسومي. Promise Callback: وتتعلق ياستدعاءات الوعود Promises. Promise Init: وتتعلق بتهيئة الوعود. Workers: تتعلق بعمّال ويب. JavaScript URI: تتعلق بعناوين موارد جافاسكربت. Event Handler: تتعلق بمعالجة الأحداث. تفسير HTML: تُمثَّل باللون وتمثِّل الوقت المستغرق في تفسير شيفرة HTML لصفحة الويب، كما تُقدِّم المعلومات على صورة مكدّس استدعاءات call stack مزوَّد بروابط إلى الدوال المستخدَمة. تفسير XML: تُمثَّل باللون وتمثِّل الوقت المستغرق في تفسير شيفرة XML لصفحة الويب، كما تُقدِّم المعلومات على صورة مكدّس استدعاءات مزوَّد بروابط إلى الدوال المستخدَمة. إعادة ضبط التنسيق Recalculate Style: تُمثَّل باللون، وتعرض الحسابات اللازمة لضبط التنسيق المحدد لعناصر الصفحة، كما تقدِّم المعلومات على صورة تلميحات لإعادة التنسيق Restyle Hint، والتي هي قيم نصية تشير إلى نوع إعادة التنسيق الواجب تطبيقه وتأخذ القيم التالية: Self. Subtree. LaterSiblings. CSSTransitions. CSSAnimations. SVGAttrAnimations. StyleAttribute. StyleAttribute_Animations. Force. ForceDescendants. ضبط التخطيط Layout: تُمثَّل باللون وتعرض الحسابات اللازمة لتحديد موقع وحجم عناصر الصفحة، كما تدعى هذه العملية بإعادة الإنسياب reflow أحيانًا. رسم الصفحة Paint: تُمثَّل باللون وترسم البكسلات على الشاشة. تجميع الموارد المستهلكة Garbage Collection تُمثَّل باللون وتعرض أحداث تجميع الموارد المستهلكة، ويُشار إلى أحداث تجميع الموارد المستهلكة اللاتصاعدي بالعبارة Non-incremental، كما تُقدِّم المعلومات على صورة قيم نصية وهي: "ReasonA": سلسلة نصية تدل على سبب استخدام مجمع الموارد المستهلكة GC. "Non-incremental Reason": سلسلة نصية تدل على سبب استخدام مجمع الموارد المستهلكة اللاتصاعدي. ستجد في فايرفوكس 46 ميزةً جديدةً هي تجميع الموارد المستهلكة، نظرًا لضغوطات ناتجة عن حجز الذاكرة، حيث يظهر في هذه الحالة رابطًا بعنوان عرض المسببات الناتجة عن حجز الذاكرة Show Allocation Triggers. انقر عندها على الرابط لتتابع ملف الأداء المتعلق بحجز الذاكرة، وصولًا إلى لحظة وقوع حدث تجميع الموارد المستهلكة. تدوير المستهلكات Cycle Collection: تُمثَّل باللون، وهي عملية تحرير بُنى البيانات التي تُخزِّن أرقام المراجع في اللغة ++C، وتشبه هذه العملية تجميع الموارد المستهلكة لكنها خاصة بكائنات ++C، وهذه العمليات دائمًا من النوع تجميع Collect. اختزال المنحني البياني لعملية تدوير المستهلكات CC Graph Reduction: تُمثَّل باللون، وتضم عمليتي التحضير أو التحسين الأولي لتدوير المستهلكات CC، وتكون هذه العمليات دائمًا من نوع تجاهل ما يمكن تجاوزه ForgetSkippable. العلامة Console: تُمثَّل باللون، وهي الفترة الزمنية بين استدعائين مترابطين للدالتين ()console.time و()console.timeEnd، كما تُقدِّم المعلومات عبر: اسم المؤقت Timer name: على هيئة وسيط يمرَّر إلى الدالة console. المكدس في البداية stack at start: يعرض حالة مكدس الاستدعاء عند استدعاء الدالة ()console.time مع روابط إلى بقية الدوال. المكدس في النهاية stack at end: وهو جديد في فايرفوكس 46، إذ يعرض حالة مكدس الاستدعاء عند استدعاء الدالة ()console.timeEnd، فإذا كان الاستدعاء داخل وعد Promise؛ فسيعرض أيضًا القيمة النصية "Async stack". العلامة Timestamp: تُمثَّل باللون، وهي استدعاء مفرد للدالة ()console.timeStamp، كما تُظهر الوسيط الذي مُرِّر إلى هذه الدالة. تحميل محتوى DOM: تُمثّل باللون، وتُظهر الحدث DOMContentLoaded. تحميل Load: تُمثّل باللون، وتظهر حدث تحميل المستند load. أحداث عمّال ويب في الخيط الأساسي Worker event in main thread: تُمثَّل باللون، وتظهر الحالات التي يرسل فيها الخيط الأساسي رسائل إلى عمّال الويب أو التي يستقبل فيها رسائل من العمّال، كما وتأخذ إحدى القيمتين: تهيئة البيانات على الخيط الرئيسي Serialize data on the main thread*، إذ يحوِّل الخيط الرئيسي الرسالة إلى صيغة مناسبة كي تُرسَل إلى العامل. تجميع البيانات على الخيط الرئيسي Deserialize data on the main thread: إذ يحوّل الخيط الرئيسي البيانات القادمة من العمال إلى بنية يمكن تخزينها أو عرضها. أحداث عمال ويب في خيط العمال Worker event in worker thread: تُمثَّل باللون، وتظهر الحالات التي يرسَل فيها العامل رسائلًا إلى الخيط الرئيسي، أو التي يستقبل فيها رسائل من الخيط الرئيسي، كما تأخذ إحدى القيمتين: تهيئة البيانات للعامل Serialize data in worker: إذ يحوِّل العامل الرسالة إلى صيغة مناسبة كي تُرسَل إلى الخيط الرئيسي. تجميع البيانات عند العامل Deserialize data in worker: ويحوِّل العامل البيانات القادمة من الخيط الرئيسي إلى بنية يمكن للعامل فهمها. تملك العلامات النمط اللوني نفسه في الأدلة Waterfall وفي لوحة النظرة العامة عندما تعرض هذه الأداة، مما يُسهِّل المطابقة بينهما. ترشيح العلامات يمكنك التحكم بالعلامات التي تريد استعراضها، وذلك من خلال زر الترشيح ضمن شريط الأدوات: أنماط لعمليات تشير إليها الأداة Waterfall يعتمد ما تعرضه لك الأداة Waterfall كثيرًا على نوع النشاط الذي يفعله موقعك، إذ ستبدو مواقع الويب التي تستخدِم جافاسكربت بشدة باللون البرتقالي، بينما سيظهر اللونين الأرجواني والأخضر بكثرة في المواقع التي تغير مظهرها المرئي بوتيرة مرتفعة، لكنك قد تلحظ بعض الأنماط التي تحذِّرك من مشاكل محتملة في الأداء. تصيير التنفيذ المتسلل لعمل المتصفح قد تعرض لك الأداة Waterfall النمط التالي: يمثل الشكل السابق تصوّرًا للخوارزمية الأساسية التي يعتمدها المتصفح في الاستجابة لحدث: استدعاء دالة جافاسكربت: تتسبب بعض الأحداث في صفحة ويب مثل أحداث DOM، بتنفيذ شيفرة جافاسكربت، وقد تغيّر هذه الشيفرة بعض أجزاء شجرة DOM أو شجرة CSSOM. إعادة ضبط التنسيق: إذا لاحظ المتصفح تغيرات في التنسيق المحسوب لعناصر الصفحة، فلا بد من إعادة الحسابات وضبط التنسيق مجددًا. تخطيط الصفحة: يستخدِم المتصفح التنسيق المحسوب حديثًا في تقدير موقع وهندسة العناصر في الصفحة.، إذ تدعى هذه العملية بتخطيط الصفحة Layout، كما تدعى أحيانًا إعادة إنسياب reflow. رسم الصفحة: لا بد أخيرًا من إعادة رسم الصفحة على الشاشة، في حين لا تظهر الخطوة الأخيرة على الشاشة، وهي إمكانية تقسيم الصفحة إلى طبقات يُعاد رسمها بصورة مستقلة، ومن ثم يعاد دمجها بعملية التركيب Composition. لا بد أن يتسع إطار واحد للتسلسل السابق طالما أنّ الشاشة لن تُحدَّث حتى اكتمال سلسلة التنفيذ السابقة، ومن المعروف أنّ معدل 60 إطار في الثانية كاف لإظهار الرسوميات المتحركة بسلاسة ونعومة على الشاشة، ويتطلب هذا من المتصفح تنفيذ السلسلة السابقة خلال 16.7 ميلي ثانية، كما من المهم معرفة من منظور الاستجابة أنّ المتصفح لا ينفِّذ بالضرورة كل خطوة من الخطوات السابقة: تُحدِّث رسوميات CSS الصفحة دون تنفيذ أيّ شيفرة جافاسكربت. لا يعيد كل تغيير في خصائص تنسيق CSS تخطيط الصفحة، وإنما فقط تلك الخصائص التي تغيِّر موقع وهندسة العناصر، مثل width أو display أو font-size أو top؛ بينما لا تغير الخصائص مثل color أو opacity تخطيط الصفحة. لا يعيد كل تغيير في خصائص تنسيق CSS رسم الصفحة، فإذا حرّكت العنصر باستخدام خاصية التنسيق transform تحديدًا، فسيستخدِم المتصفح طبقةً منفصلةً للعنصر الذي طُبقت عليه تلك الخاصية، ولا حاجة حتى لإعادة الرسم عندما يتحرك العنصر، وإنما يُضبَط موقعه وهندسته أثناء عملية تركيب الطبقات. سنطلع لاحقًا على تأثير رسوم CSS المتحركة على الأداء، وكيف تساعد الأداة Waterfall في الإشارة إلى ذلك. حجب جافاسكربت تُنفَّذ جافاسكربت افتراضيًا على الخيط نفسه الذي يستخدِمه المتصفح لتحديث تخطيط الصفحة وإعادة الرسم وتنفيذ أحداث DOM وغيرها، وهكذا فإنّ تنفيذ دوال جافاسكربت يستغرق وقتًا طويلًا قد يسبب توقف استجابة الصفحة وخشونةً في عرض الرسوميات، كما قد تتجمد الصفحة بالكامل، في حين يمكن بسهولة رصد الأوقات التي تسبب فيها شيفرة جافاسكربت مشاكلًا في الاستجابة باستخدام الأداتين Frame rate وWaterfall معًا. لاحظ كيف حددنا في الشكل التالي منطقةً سببت فيه دالة جافاسكربت نقصًا في معدل الإطارات. سنطّلع في مقال تأثير الاستخدام المكثف لجافاسكربت على الأداء على أهمية الأداة Waterfall في تحديد مشاكل الاستجابة التي تسببها دوال جافاسكربت وكيفية استخدام التوابع غير المتزامنة للمحافظة على استجابة خيط التنفيذ. عملية رسم عناصر مستنزفة للوقت قد تستنزف بعض تأثيرات رسم العناصر وقتًا طويلًا مثل box-shadow، وخاصةً عند تطبيق هذه التأثيرات في حالات تحريك العناصر، إذ ينبغي على المتصفح إعادة ضبط هذه التأثيرات مع كل إطار، فإذا لاحظت انخفاضًا في معدل الإطارات عند تنفيذ عمليات رسومية كثيفة أو عمليات تحريك للعناصر خصوصًا، فتحقق من العلامات الخضراء في الأداة Waterfall. تجميع الموارد المستهلكة تشير العلامات الحمراء في الأداة Waterfall إلى عمليات تجميع الموارد المستهلكة GC -بغية تحرير الذاكرة المرتبطة بها-، إذ يتجول محرك جافاسكربت والذي يُدعى SpiderMonkey في فايرفوكس في كومة الذاكرة عن المناطق التي لم يَعُد بالإمكان الوصول إليها وتحريرها، وتؤثر هذه العملية في الأداء لأنه لا بد من إيقاف محرك جافاسكربت عن تنفيذ الشيفرة مؤقتًا عندما تبدأ عملية تجميع الموارد المستهلكة، وبالتالي سيُعلَّق تنفيذ برنامجك وقد لا يستجيب إطلاقًا. ينفذ المحرك SpiderMonkey ما يسمى التجميع المتصاعد للموارد المستهلكة incremental GC لتخفيف هذه المشكلة في فايرفوكس، إذ تقتضي هذه العملية تنفيذ عملية تجميع الموارد المستهلكة على دفعات متصاعدة صغيرة تلائم تنفيذ البرنامج خلالها، لكن لا بد في بعض الحالات من تنفيذ عملية تجميع موارد مستهلكة لا تصاعدي، وبالتالي على البرنامج الانتظار حتى نهاية العملية، كما من الأفضل عدم محاولة تخصيص طريقة لتفادي عملية تجميع موارد مستهلكة لمحرك جافاسكربت معيّن وخاصةً أحداث تجميع الموارد المستهلكة التصاعدية، إذ يستخدِم SpiderMonkey مثلًا مجموعةً معقدةً من الطرق الاستدلالية لتقدير الحاجة إلى استخدام عملية تجميع الموارد المستهلكة اللاتصاعدية والتصاعدية خصوصًا، ويمكن القول أنه: نحتاج إلى تجميع الموارد المستهلكة عندما تُحجَز مساحات كبيرة من الذاكرة. نحتاج إلى تجميع الموارد تصاعديًا عندما يكون معدل حجز الذاكرة مرتفعًا إلى الحد الذي تستنزف فيه ذاكرة محرك جافاسكربت عند تنفيذ التجميع اللاتصاعدي. عندما تسجل الأداة Waterfall علامة تجميع موارد مستهلكة، فهي تشير إلى: العملية تصاعدية أم لا. سبب تنفيذ العملية. سبب تنفيذ العملية اللاتصاعدية إذا كانت كذلك. ستجد في فايرفوكس 46 وما بعد ميزةً جديدةً هي تجميع الموارد المستهلكة على أساس نتيجة لضغوطات ناتجة عن حجز الذاكرة، حيث يظهر في هذه الحالة رابطًا بعنوان عرض المسببات الناتجة عن حجز الذاكرة Show Allocation Triggers، وانقر عندها على الرابط لتتابع ملف الأداء المتعلق بحجز الذاكرة، وصولًا إلى لحظة وقوع حدث تجميع الموارد المستهلكة، كما سنعرض هذه الموضوع لاحقًا بشيء من التفصيل. إضافة العلامات من خلال الواجهة البرمجية للطرفية يمكن التحكم بعلامتين فقط من خلال الواجهة البرمجية للطرفية Console API هما: "Console" و"Timestamp". علامات Console تساعدك على تحديد قسم محدد من التسجيل، وبالتالي استدع الدالة ()console.time في بداية القسم الذي تريد تحديده والدالة ()console.timeEnd عند نهايته، كما تقبل هاتين الدالتين وسيطًا يُستخدَم في تسمية هذا القسم، ولنفرض مثلًا أننا أمام الشيفرة التالية: var iterations = 70; var multiplier = 1000000000; function calculatePrimes() { console.time("calculating..."); var primes = []; for (var i = 0; i < iterations; i++) { var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } console.timeEnd("calculating..."); return primes; } سيبدو خرج الأداة waterfall كما يلي: تُحدَّد العلامة من خلال الوسيط الذي مُرِّر إلى الدالة ()console.time، كما يمكنك متابعة مكدس البرنامج ضمن الشريط الجانبي إلى اليمين عندما تختار هذه العلامة. أما بخصوص مكدس العملية اللامتزامنة Async stack، فسيعرِض الشريط الجانبي ابتداءً من النسخة فايرفوكس 41 حالة المكدس في نهاية التسجيل عند استدعاء ()console.timeEnd، فإذا استدعيت ()console.timeEnd من داخل وعد Promise، فسيعرض الشريط العبارة "(Async: Promise)" وسترى تحتها العبارة "async stack" التي تدل على حالة مكدس الاستدعاء في لحظة تنفيذ الوعد، وتأمل الشيفرة التالية على سبيل المثال: var timerButton = document.getElementById("timer"); timerButton.addEventListener("click", handleClick, false); function handleClick() { console.time("timer"); runTimer(1000).then(timerFinished); } function timerFinished() { console.timeEnd("timer"); console.log("ready!"); } function runTimer(t) { return new Promise(function(resolve) { setTimeout(resolve, t); }); } وستعرض الأداة Waterfall علامةً للفترة الزمنية المنقضية بين الاستدعائين ()time و()timeEnd، فإذا نقرت عليها، فستشاهد المكدس اللامتزامن ضمن الشريط الجانبي: علامات Timestamp تساعدك هذه العلامة على تحديد لحظة زمنية ضمن التسجيل، لذا استدع الدالة ()console.timeStamp لتضع علامة timestamp، كما يمكنك تمرير اسم لهذه العلامة من خلال تمرير الاسم على أساس وسيط للدالة السابقة، ولنفترض أننا عدلنا الشيفرة التي عرضناها سابقًا لتحديد لحظة زمنية كل 10 تكرارات للحلقة على سبيل المثال، ونختار عدد التكرارات على أساس اسم لهذه اللحظة: var iterations = 70; var multiplier = 1000000000; function calculatePrimes() { console.time("calculating..."); var primes = []; for (var i = 0; i < iterations; i++) { if (i % 10 == 0) { console.timeStamp(i.toString()); } var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } console.timeEnd("calculating..."); return primes; } ستعرض الأداة waterfall شيئًا من هذا القبيل: الأداة Frame rate يُعَدّ معدّل الإطارات مقياسًا لاستجابة الصفحة، وقد تتسم الصفحات التي تتمتع بمعدل إطارات ضعيف أو غير مستقر بضعف الاستجابة أو الجمود، مما يؤثر على تجربة المستخدِم. يتيح الرسم البياني لمعدل الإطارات في الأداة Performance إمكانية إظهار تغير معدل الإطارات خلال فترة التسجيل، ويدلك بسرعة إذا كانت الصفحة ستعاني من مشاكل في الأداء وتمكِّنك من استخدام بقية الأدوات الجزئية بفعالية أكبر لتحليل المشكلة. علاقة معدل الإطارات باستجابة الصفحة يُعرَّف معدل الإطارات تقليديًا بأنه معدّل التقاط الصور أو الإطارات بواسطة جهاز فيديو، وهو مألوف جدًا في عالم التصوير والألعاب، لكنه يستخدَم حاليًا على نطاق واسع في قياس أداء موقع ويب أو تطبيق ويب، حيث يمثِّل الإطار -عند تقييم الأداء في ويب- العمل الذي ينبغي على المتصفح تنفيذه لتحديث وإعادة رسم الشاشة، كما تُعَدّ الرسوم المتحركة النواحي الأكثر التي يُطبق فيها هذا المقياس، فإذا كان المعدل منخفضًا جدًا، فستكون استجابة الرسوم المتحركة بطيئةً وخشنةً، في حين سيكون عرض الرسوم أكثر سلاسةً عندما يكون معدل الإطارات أسرع، ومع ذلك يُعَدّ معدل الإطارات مفيدًا في قياس مدى استجابة المواقع عندما يتفاعل معها المستخدِم. إذا أدى تمرير مؤشر الفأرة على سبيل المثال فوق أحد عناصر صفحة ويب إلى وقوع حدث من أحداث جافاسكربت يغير مظهر ذلك العنصر، فسيؤدي ذلك إلى تنفيذ عمليتَي إعادة تخطيط العناصر ضمن الصفحة، ثم إعادة رسم الشاشة، ولا بد من اكتمال هذه العمليات جميعها في إطار واحد، فإذا استغرق أمر معالجة هذا الإطار من قِبَل المتصفح وقتًا طويلًا، فستتوقف استجابة المتصفح مؤقتًا، وكذلك الأمر عندما تتنقل ضمن صفحة تتطلب العديد من عمليات التحديث المعقدة بحيث لا يتمكن المتصفح من المحافظة على معدل إطارات مقبول، وهنا ستلاحظ بطأً في تمرير الصفحة صعودًا أو نزولًا وقد تتجمد أثناء ذلك، فعندما يكون معدل الإطارات مرتفعًا وثابتًا عمومًا، فسيريح ذلك المستخدِم ويجعل تجربته أكثر متعةً. يقدِّم معدل 60 إطار في الثانية أداءً سلسلًا ويتيح فترةً زمنيةً مقدارها 16.7 ميلي ثانية لإنجاز كل التحديثات المطلوبة، وذلك بالتزامن مع الاستجابة إلى بعض الأحداث، ولا بد من الإشارة إلى الأهمية الخاصة للاستمرارية أو ثبات معدل الإطارات، فإذا لم تستطع تحقيق 60 إطار في الثانية، فحاول تحقيق معدل أقل لكن على فترات زمنية طويلة -أي الاستمرارية-، وتفادي أيّ انخفاض مفاجئ قد يسبب جمود الصفحة. المخطط البياني لمعدل الإطارات ستجد هذا المخطط البياني في قسم النظرة العامة للتسجيل ضمن الأداة Performance، حيث يلتقط المخطط اللحظة الزمنية التي ينهي فيها المتصفح إطارًا، ويستخدِمها ليتتبع معدل الإطارات أثناء فترة التسجيل. يمثِّل المحور X الزمن المنقضي أثناء تسجيل ملف الأداء، كما ستلاحظ وجود ثلاث مؤشرات هي معدل الإطارات الأعظمي ومعدل الإطارات الوسطي ومعدل الإطارات الأقل. طريقة استخدام المخطط البياني لمعدل الإطارات تدل قيمة معدل الإطارات على بعض المشاكل المحتملة التي قد تواجهها الصفحة، وبالتالي سيساعدك ذلك في استخدام أدوات أخرى لتحليل مشاكل الأداء بعمق أكثر، وإليك على سبيل المثال لقطة الشاشة التالية لملف أداء: ستجد أنّ معدل الإطارات الوسطي جيد، لكنك ستلاحظ أيضًا ثلاث لحظات ينهار فيها معدل الإطارات خلال أعشار من الميلي ثانية، إذ يسبب ذلك دون أي شك تعثرًا ملحوظًا في عرض الرسوم المتحركة ضمن الصفحة، كما يرتبط معدل الإطارات مع عرض مختصر لعلامات الأداة waterfall فوقه مباشرةً، ولاحظ كيف ترافق أول انهيارين في معدل الإطارات في اللقطة السابقة مع شريط برتقالي يدل على الوقت المستغرَق في تنفيذ شيفرة جافاسكربت، فإذا اخترنا شريحةً تضم إحدى هاتين اللحظتين، فسيعرض قسم التفاصيل في الأسفل تفاصيل هذه الشريحة، وسنتابع الدالة التي سببت المشكلة: لاحظ كيف أعاقت دالة جافاسكربت استُدعيت عند حدث النقر خيط التنفيذ الرئيسي عن العمل مدة 170 ميلي ثانية، ولمعرفة هذه الدالة تحديدًا انتقل إلى الأداة Flame Chart لمتابعة مكدّس الاستدعاءات في هذه النقطة: هذه الدالة إذًا ()doPointlessComputations وهي دالة معرفة في الملف "main.js"، وقد نضطر لحل المشكلة إلى تقسيم الدالة إلى أجزاء، وتنفيذ كل جزء على حدة ضمن requestAnimationFrame أو تنفيذها بالكامل ضمن عامل ويب، وسنتابع لاحقًا حلولًا لمشاكل مثل هذه عندما نحلل تأثير الاستخدام المكثف لجافاسكربت على الأداء. الأداة Call Tree تساعدك هذه الأداة على تحديد دوال جافاسكربت التي يقضي المتصفح الوقت الأطول في تنفيذها، كما تساعدك عند تحليل النتائج التي تعرضها على إيجاد الاختناقات في شيفرتك، أي الأماكن التي يقضي فيها المتصفح وقتًا طويلًا بلا مبرر، إذ تُعَدّ نقاط الاختناق هذه هي الهدف الأفضل للتحسينات التي يمكن إجراؤها على الشيفرة والأكثر تأثيرًا. تُعَدّ الأداة Call Tree أداةً لتجميع العينات، إذ تلتقط دوريًا عينات لتحديد حالة محرك جافاسكربت وتسجيل حالة المكدّس في زمن تنفيذ الشيفرة، في حين يتعلق عدد العينات المجمّعة إحصائيًا عند تنفيذ دالة محددة بالزمن الذي يستغرقه المتصفح في تنفيذها، ولشرح فائدة الأداة Call Tree، سنستخدم خرج برنامج بسيط على أساس مثال، فإذا أردت الحصول على هذا البرنامج لتجربه بنفسك، فيمكنك تنزيله من المستودع الخاص به على جيت هاب، كما يمكنك تنزيل ملف الأداء الذي سنشرحه من المستودع ذاته وإدراجه بعد ذلك ضمن الأداة Performance، وستجد كذلك شرحًا مختصرًا عن هيكلية البرنامج ضمن المستودع. تعرض لقطة الشاشة التالية خرج برنامج يوازن بين ثلاثة خوارزميات للفرز، وهي الفرز الفقاعي Bubble Sort والفرز الانتقائي Selection Sort والفرز السريع Quicksort؛ حيث يولِّد البرنامج لتنفيذ الاختبار بعض المصفوفات التي تضم أرقامًا صحيحةً عشوائيةً، ثم يفرزها باستعمال كل خوارزمية على حدة، وقد ركزنا في قسم الحالة العامة Recording overview على منطقة ظهرت فيها علامة طويلة لجافاسكربت: تعرض الأداة Call Tree النتائج ضمن جدول يمثِّل فيه كل صف دالةً التَقطت منها الأداة عينةً واحدةً على الأقل ورتبت أسطرها حسب عدد العينات المأخوذة أثناء تواجدها في الدالة، ترتيبًا تنازليًا، بينما تمثِّل الأعمدة القيم التالية: العينات Samples: تشير إلى عدد العينات التي التُقطت عند تنفيذ دالة معينة بما في ذلك الدوال الأبناء وهي الدوال التي تُستدعيها هذه الدالة. الوقت الكلي Tota lTime: يقدَّر بالميلي ثانية ويمثِّل الوقت الكلي الذي تستغرقه شريحةً محددةً من التسجيل، كما يماثل تقريبًا عدد العينات. التكلفة الكلية Total Cost: يمثِّل النسبة المئوية للعدد الكلي للعينات في القسم المختار من التسجيل. التوقيت الذاتي Self Time: يمثِّل الوقت الذي يستغرقه تنفيذ دالة محددة دون النظر إلى زمن تنفيذ أبنائها، حيث يُقدَّر هذا الزمن من حالة المكدسات المُلتقَطة في اللحظات التي تكون فيها الدالة آخر عناصر المكدس leafmost function. التكلفة الذاتية Self Cost: تُحسب من التوقيت الذاتي على أساس نسبة مئوية للعدد الكلي من عينات القسم المحدد من التسجيل. تمثِّل الأعمدة السابقة القيم الأهم في النسخة الحالية من الأداة Call Tree، ويُفضَّل إجراء تحسين للشيفرة انطلاقًا من الدوال التي تمتلك قيمة تكلفة ذاتية مرتفعة لأنها تستغرق وقتًا طويلًا في التنفيذ، أو لأنها تُستدعى بكثرة. تخبرنا أخيرًا لقطة الشاشة السابقة عن شيء ربما نعرفه بالفعل، وهو أنّ خوارزمية الفرز الفقاعي فعالة جدًا، فعدد العينات الملتقَطة في القسم الذي يسجل عملها يزيد 6 مرات عن عدد عينات القسم الذي يسجل عمل خوارزمية الفرز الانتقائي، و13 مرة عن خوارزمية الفرز السريع. التنقل ضمن الأداة Call Tree يوجد سهم صغير إلى جوار اسم كل دالة، وسترى عند النقر على هذا السهم مسار استدعاء هذه الدالة رجوعًا إلى بدايته، أي من الدالة التي التقطت العينة أثناء تنفيذها وحتى الدالة الجذرية، إذ يمكن مثلًا توسيع الدالة ()bubbleSort: سيظهر المخطط البياني للاستدعاء كما يلي: sortAll() -> sort() -> bubbleSort() التُقِطت 253 عينة داخل الدالة ()swap، لكن يوجد مساران مختلفان يقودان إلى هذه الدالة، إذ تستخدِمها كلتا الدالتَين ()bubbleSort و()selectionSort، كما يمكننا ملاحظة أنّ 252 عينة من أصل 253 ضمن الدالة ()swap قد التُقِطت من مسار الدالة ()bubbleSort وعينةً واحدةً فقط من المسار الآخر. تشير هذه النتيجة إلى أنّ خوارزمية الفرز الفقاعي أقل فعاليةً مما نظن، فهي تتحمل في الواقع مسؤولية 252 عينة إضافية، أي حوالي 10% أخرى من التكلفة الكلية، كما يمكننا الحصول على المخطط البياني الكامل مع عدد العينات الموافق بمتابعة طريقة التحليل هذه: sortAll() // 8 -> sort() // 37 -> bubbleSort() // 1345 -> swap() // 252 -> selectionSort() // 190 -> swap() // 1 -> quickSort() // 103 -> partition() // 12 بيانات منصة العمل سترى بعض الأسطر التي تحمل قيمًا مثل Gecko أو Input & Events وغيرها، بحيث تمثِّل الاستدعاءات الداخلية للمتصفح، كما تقدِّم لك بيانات هذه الأسطر معلومات قيمةً أيضًا، فقد لا تجد أية عينات تشير إلى مدى صعوبة تنفيذ شيفرة موقعك في المتصفح، وستجد في مثالنا 679 عينة مرتبطة بالقيمة Gecko، وهي ثاني أكبر مجموعة من العينات بعد عينات الدالة ()bubbleSort، فلنوسِّع إذًا معلومات Gecko: تشيرالنتائج إلى أنّ مصدر 614 عينة من هذه العينات أو حوالي 20% من التكلفة الكلية هي من استدعاء الدالة ()sort، فإذا نظرنا إلى شيفرة هذه الدالة، فسنلاحظ بوضوح أنّ سبب التكلفة المرتفعة لعمل المنصة -أو مجهود المتصفح- هو الاستدعاء المتكرر للتابع ()console.log: function sort(unsorted) { console.log(bubbleSort(unsorted)); console.log(selectionSort(unsorted)); console.log(quickSort(unsorted)); } إذًا من الأفضل التفكير بطريقة أخرى لتنفيذ الأمر. لاحظ أيضًا أنّ زمن الخمول idle time يصنَّف على أساس Gecko، أي أنّ أقسام ملف الأداء التي لم تُنفَّذ أثناء تسجيلها أيّ شيفرة جافاسكربت أثناء التنفيذ ستصنف على أنها عينات Gecko، ولا يتعلق هذا التصنيف طبعًا بأداء الصفحة. الصيغة المعكوسة (المقلوبة) للأداة Call Tree ببساطة هي صيغة ينعكس فيها ترتيب جميع المكدّسات، بحيث تكون آخر الدوال المستدعاة في قمة المكدس، وبهذه الطريقة سيركِّز عرض البيانات أكثر على معلومات التوقيت الذاتي للدوال Self Time، وبالتالي ستحصل على معلومات أكثر حساسية في شيفرتك، ولإظهار الأداة بالصيغة المعكوسة، انقر على أيقونة التبديل في أقصى يمين نافذة الأداء ثم اختر Invert Call Tree. الأداة Flame Char تعرض لك هذه الأداة حالة مكدس جافاسكربت كل ميلي ثانية أثناء تسجيل ملف الأداء، كما يتيح لك ذلك معرفة الدالة التي يجري تنفيذها في كل لحظة من لحظات التسجيل وزمن تنفيذها ومسار استدعائها، كما تُستخدَم الأداتين Call Tree وFlame Chart في تحليل شيفرة جافاسكربت في موقعك وتستخدمان البيانات ذاتها المتمثلة بعينات من المكدس الخاص بمحرك جافاسكربت الملتقَطة دوريًا أثناء تسجيل ملف الأداء. ستعرض لك الأداة Flame Chart متى يجري تنفيذ دالة معينة خلال زمن التسجيل بينما تنظم الأداة Call Tree البيانات لعرض الدوال التي يقضي البرنامج وقتًا أكبر في تنفيذها، كما تعرض لك بصورة أساسية حالة مكدس الاستدعاء في أية لحظة من لحظات زمن التسجيل، وإليك لقطة شاشة تُظهر بيانات الأداة Flame Chart لشريحة من ملف الأداء: يمكننا في البداية ملاحظة أننا اخترنا شريحةً صغيرةً من التسجيل لعرض بيانات Flame Chart لها ضمن لوحة النظرة العامة، لأن البيانات التي تقدمها هذه الأداة كثيرة وتصعب متابعتها، لذلك كان لا بد من تضييق نطاق العرض، كما يمثِّل المحور X في لقطة الشاشة السابقة الزمن، في حين تغطي هذه اللقطة الفترة الزمنية الممتدة بين اللحظة 1435 ميلي ثانية و1465 ميلي ثانية، وتتوزع أيضًا على امتداد المحور Y، الدوال الموجودة في مكدس الاستدعاء خلال هذه الفترة من الدوال الأعلى مستوى في الأعلى إلى أخفضها مستوًى في الأسفل، وصُنِّفت الدوال وفق نظام لوني ليسهُل التمييز بينها. يمنحك هذا الأسلوب في عرض البيانات إمكانية معرفة الدالة التي يجري تنفيذها في أية لحظة خلال فترة التسجيل، والوقت المستغرَق في تنفيذها ومسار استدعائها. تغيير مجال العرض وإزاحة الشرائح ينبغي أن تكون قادرًا على التنقل بين البيانات المعروضة بسهولة لكي تستطيع العمل بفعالية أكبر، حيث تقدِّم الأداة Flame Chart وسيلتَي تحكم لهذا الغرض: Zoom (تغيير مجال العرض): لزيادة أو إنقاص مجال الشريحة المختارة من ملف التسجيل الكامل الذي يُعرَض ضمن الأداة Flame Chart، حيث تستطيع استخدام هذه الوسيلة كما يلي: دحرجة دولاب الفأرة للأعلى والأسفل ضمن Flame Chart. تحريك إصبعَين معًا للأعلى أو للأسفل على لوحة اللمس ضمن Flame Chart. Pan (التنقل بين الشرائح): إزاحة الشريحة التي اخترتها من ملف التسجيل الكامل يمينًا أو يسارًا، إذ تستطيع استخدام هذه الوسيلة كما يلي: انقر على الشريحة المختارة ضمن لوحة النظرة العامة واسحبها بالاتجاه المطلوب. انقر واسحب في أي مكان ضمن Flame Chart. مثال تطبيقي سنلقي نظرةً على مثال بسيط هو نفسه البرنامج الذي استخدمناه سابقًا لتتابع كيف ستكشف الأداة Flame Chart سلوك برنامجك ولتوضيح عمل الأداة Call Tree، كما سنستخدم ملف الأداء نفسه، فقد وجدنا أنُ تسلسل الاستدعاءات وتعداد العينات المقابل لكل منها في ملف الأداء هو كما يلي: sortAll() // 8 -> sort() // 37 -> bubbleSort() // 1345 -> swap() // 252 -> selectionSort() // 190 -> swap() // 1 -> quickSort() // 103 -> partition() // 12 اخترنا في البداية المقطع الذي كان البرنامج فيه مشغولًا بأكمله: لاحظ وجود الدالة ()sortAll الملونة بالأرجواني في القمة، حيث يمتد زمن تنفيذها من بداية البرنامج حتى نهايته، وتأتي تحتها مباشرةً الدالة ()sort باللون الأخضر الزيتوني، ويليها تعاقب استدعاءات مثل أسنان المشط لكل خوارزمية من خوارزميات الفرز الثلاث، ولنقرِّب المشهد أكثر: تمتد الشريحة مدة 140 ميلي ثانية وتعرض تفاصيلًا أكثر عن الدوال التي تستدعيها الدالة ()sort. لاحظ الشيفرة التي تكوّن الدالة ()sort: function sort(unsorted) { console.log(bubbleSort(unsorted)); console.log(selectionSort(unsorted)); console.log(quickSort(unsorted)); } تمثِّل العلامة التي يبدو عنوانها "…bubb" وملوّنةً بالأخضر الزيتوني الدالة ()bubbleSort، في حين تمثل العلامة الأخرى التي تبدو باللون الأخضر الصرف بقية دوال الفرز. لاحظ أنّ كتلة دالة الفرز الفقاعي ()bubbleSort ذات عرض أكبر -أي تمتد لفترة أطول- من البقية، كما يمكن ملاحظة مجموعة دوال تستدعيها الدالة ()bubbleSort وتبدو باللون الأرجواني، ولنقرّب المشهد مرة أخرى: يساوي عرض الشريحة الأخيرة التي اخترناها حوالي 20 ميلي ثانية، وسنرى بوضوح أنّ العلامة الأرجوانية أسفل الدالة ()bubbleSort هي استدعاءات للدالة ()swap، فإذا أحصينا هذه الاستدعاءات، فسترى أنها 253 وفقًا للأداة Call Tree، كما تشير Call Tree إلى وقوع كل الاستدعاءات السابقة تحت الدالة ()bubbleSort ماعدا استدعاء وحيد يقع تحت الدالة ()selectionSort، كما يمكن أيضًا رؤية وجود علامتين خضراوين للدالتين ()selectionSort و()quickSort، وسنرى استدعاءات لمنصة العمل في الفترة ما بين استدعاءات دوال الفرز، كما من المرجح أن يكون سببها استدعاء الدالة ()console.log من داخل الدالة ()sort. الأداة Allocations تعرض لك الأداة Allocations الدوال التي تحجز مساحةً أكبر من الذاكرة خلال فترة تسجيل ملف الأداء، ويُعَدّ الأمر مهمًا من ناحية الأداء، لأن حجز مساحات كبيرة من الذاكرة أو إشغال مناطق كثيرة منها قد يؤدي إلى وقوع حدث تجميع الموارد المستهلكة garbage collection، والذي يؤثر بدوره سلبًا على استجابة الصفحة، كما تُعَدّ هذه الأداة جديدةً في فايرفوكس 46. عليك تفعيل خيار تسجيل حجوزات الذاكرة Record Allocations ضمن إعدادات الأداة Performance قبل تسجيل ملف الأداء لكي تشاهد هذه الأداة، وعند تسجيل الملف بعد ذلك سترى نافذةً فرعيةً جديدةً عنوانها Allocations في شريط الأدوات. تشريح لوحة الأداة Allocations تبدو اللوحة كما في الصورة التالية: تأخذ الأداة عينات دوريًا من مساحات الذاكرة المحجوزة K بحيث يمثِّل كل صف دالةً أُخذِت عينة واحدة على الأقل من مساحة الذاكرة التي تحجزها أثناء تسجيل ملف الأداء، كما يضم جدول عرض البيانات الأعمدة التالية: Self Count العداد الذاتي: عدد عينات الحجز التي التُقِطت ضمن الدالة المحددة، وتُعرَض أيضًا على أساس نسبة مئوية من عدد العينات الكلي. Self Byte عدد البايتات الذاتي: العدد الكلي للبايتات الموجودة في عينة ملتقَطة داخل دالة، تُعرَض أيضًا على أساس نسبة مئوية من الكمية الكلية، كما تُرتَّب الأعمدة وفقًا لعدد البايتات الذاتي. سنجد في مثالنا السابق ما يلي: تمثل العينات الملتقَطة في الدالة ()signalLater ما مقداره 28.57% من العدد الكلي للعينات البالغ 8904. تحجز هذه العينات 1102888 بايت، أي ما مقداره 30.01% من الذاكرة الكلية المحجوزة في جميع العينات. سترى الأماكن التي تُستدعى منها كل دالة بالنقر على السهم الصغير بجوار اسمها: لاحظ كيف استُدعيت الدالة ()signalLater من مكانين هما ()removeInner و()setSelectionInner،إذ ستتمكن الآن من الرجوع خطوةً ضمن المكدس لفهم سياق حجز الذاكرة بصورة أفضل. التكلفة الذاتية والتكلفة الكلية تعرض لك الأداة مجموعتين من الأعمدة يبدأ عنوان الأولى بالكلمة Self والثانية بالكلمة Total، إذ تسجِّل الأولى العينات الملتقَطة من دالة واحدة، بينما تسجِّل الثانية العينات الملتقَطة من هذه الدالة أو الدوال التي استدعتها هذه الدالة، كما ستتطابق هاتين المجموعتين بالنسبة للدوال التي تمثل قمة المكدس طالما أن الدوال الأخيرة في المكدس ستظهر في الأعلى، أي ما نراه هو صيغة معكوسة لمكدس الاستدعاء، لكن إذا بدأت التراجع إلى الخلف في المكدس، فسترى الفرق بين المجموعتين: التقَطت الأداة 8904 عينةً في الدالة ()signalLater، لكن هذه الدالة قد استُدعيت من مكانين ()removeInner و()setSelectionInner، وتبدو قيمة العداد الذاتي لهما 0 بمعنى أنهما لا تحجزان مباشرةً أية ذاكرة، لكن قيمة العداد الكلي للدالة ()removeInner هي 8901 وقيمته للدالة ()setSelectionInner هي 3 فقط، أي أنّ معظم الحجوزات التي نراها في الدالة ()signalLater مصدرها الدالة ()removeInner. حجز الذاكرة وتجميع الموارد المستهلكة إنّ أية معلومات عن الذاكرة التي يحجزها موقع جديرة بالاهتمام، لكن الرابط الحقيقي بين استجابة موقع وكمية الذاكرة المحجوزة هو موضوع تجميع الموارد المستهلكة GC، كما يتحقق محرك التنفيذ من وجود كائنات مستهلكة لا يمكن الوصول إليها في كومة الذاكرة الخاص بالبرنامج في جميع اللغات التي تعتمد أسلوب تجميع الموارد المستهلكة مثل جافاسكربت، ثم يحرر الذاكرة التي تحجزها تلك الكائنات، وعند تنفيذ هذه العملية يتوقف محرك جافاسكربت مؤقتًا ويُعلَّق عمل البرنامج وتتوقف استجابته. يُنفِّذ SpiderMonkey محرك جافاسكربت على فايرفوكس هذه العملية تصاعديًا بخطوات صغيرة لتخفيف هذا الأثر على الاستجابة، فيسمح باستمرارية عمل البرنامج ما بين هذه الخطوات، لكن لا بد في بعض الحالات من تنفيذ عملية تجميع موارد مستهلكة لا تصاعدي، وبالتالي على البرنامج الانتظار حتى نهاية العملية، كما تظهر أحداث تجميع الموارد المستهلكة باللون الأحمر في لوحة الأداة Waterfall، وقد تلاحظ رايات حمراء طويلة ترتبط بانعدام استجابة البرنامج قد تمتد فترة عدة مئات من الميلي ثانية. ما الذي تستطيع فعله عندما ترى أحداث GC في ملف أداء برنامجك؟ يستخدِم SpiderMonkey مجموعةً معقدةً من الطرق الاستدلالية لتقدير الحاجة إلى استخدام طريقة معينة في تجميع الموارد المستهلكة، لكن الضغوطات الناتجة عن حجز الذاكرة -أي حجز مساحات كبيرة أو معدل حجز مرتفع للذاكرة- ستدفع SpiderMonkey إلى تنفيذ عمليات GC، وعلى الأغلب التجميع الكامل اللاتصاعدي عوضًا عن التصاعدي. إذا وقعت أحداث تجميع الموارد المستهلكة بسبب ضغوطات ناتجة عن حجز الذاكرة، فسيظهر في هذه الحالة رابطًا بعنوان عرض المسببات الناتجة عن حجز الذاكرة Show Allocation Triggers ضمن الشريط الجانبي إلى يمين نافذة الأداة Waterfall، فإذا نقرت على هذا الرابط، فستنتقل أدوات التطوير إلى عرض النافذة Allocations وستختار الفترة الزمنية الممتدة من نهاية آخر دورة لتجميع الموارد المستهلكة حتى بداية الدورة التي نقرت عليها، وسيعرض لك ذلك كل حجوزات الذاكرة التي أدت بمجموعها إلى وقوع حدث تجميع الموارد المستهلكة، فإذا واجهتك هذه المشكلة، فحاول إذا استطعت اختزال عدد أو حجم حجوزات الذاكرة: هل يمكنك حجز ذاكرة محدودة؟ أي فقط عندما تحتاجها بدلًا من حجزها منذ البداية. هل تجري عملية الحجز ضمن حلقة؟ إذا كان الأمر كذلك، فهل بالإمكان إعادة استخدام الذاكرة المحجوزة نفسها عند كل تكرار للحلقة؟ ترجمة -وبتصرف- للمقالات التالية: Waterfall. Frame rate. Call Tree. Flame Chart. Allocations. اقرأ أيضًا مراقبة وتحليل أداء صفحات الويب باستخدام الأداة Performance تحسين الظهور في محركات البحث
-
توفر الواجهة البرمجية لعامل الخدمة Service Worker أدوات متعددةً وواسعة الاستخدامات، تتميز بمرونتها وتقديمها لأداء أفضل، إذا لم تستخدم عامل الخدمة سابقًا -ولا يمكن لومك على ذلك لأنه لم يلق تبنيًا واسعًا حتى عام 2020- فإليك طريقة عمله: عند أول زيارة إلى الموقع سيسجل المتصفح وكيلًا من طرف العميل، يعمل على كمية صغيرة من جافاسكربت تعمل في خيط thread خاص بها، مثل عامل الويب. بعد تسجيل عامل الخدمة يمكنك مقاطعة الطلبات الصادرة، وتحديد كيفية الرد عليها في حدث عامل الخدمة ()fetch. ما ستفعله للطلبات التي تُقاطعها يعود لك ويعتمد على موقعك الإلكتروني، يمكنك إعادة كتابة الطلبات، والتخزين المؤقت المسبق للملفات الثابتة أثناء التثبيت، وتقديم ميزة العمل بدون اتصال بالإنترنت، وتوصيل حمولات أصغر من HTML لتقديم أداء أفضل لزوّار الموقع المتكررين، وهو ما سنركز عليه في مقالنا. تجاوز الاتصال الضعيف بالشبكة سنشرح حالةً عمليةً لتوضيح الفكرة، ففي ولاية ويسكونسون الأميركية قدمت شركة ويكلي تيمبر Weekly Timber خدمات قطع الأشجار ونقلها، وبالطبع ستلعب سرعة أداء الموقع دورًا كبيرًا في عملهم، فمكان عمل الشركة هو مقاطعة واشيرا Waushara في الولاية، وليست جودة الاتصال بالشبكة ووثوقيتها هناك جيدةً، مثل العديد من المناطق الريفية في الولايات المتحدة الأميريكية. توضح الخارطة تغطية الشبكة اللاسلكية في مقاطعة واشيرا في ولاية ويسكونسون، حيث تعني المناطق ذات اللون الأسمر سرعات منخفضةً تتراوح بين 3 إلى 9.99 ميجا بت في الثانية، بينما تعني المناطق ذات اللون الأحمر سرعات أبطأ من ذلك، والمناطق ذات اللونين الأزرق الداكن والباهت السرعات الأسرع من ذلك. تحوي ولاية ويسكونسون أراض زراعيةً شاسعةً، بالإضافة إلى العديد من الغابات، وعندما تحتاج لخدمات شركة لتقطيع الخشب، فستكون أول وجهة للبحث عنها هي جوجل، وسيحدد بطء موقع الشركة ما إذا كنت ستبحث عن شركة أخرى، بسبب جودة الاتصال بالشبكة السيئة هناك. لم تكن ضرورة إضافة عامل الخدمة لموقع الشركة واضحةً في بادئ الأمر، فما دام موقع الشركة يعمل بسرعة فلا حاجة لتعقيد الأمور، لكن بعد معرفة أن الشركة تخدّم زبائنًا خارج مقاطعة واشيرا، وحتى وسط ويسكونسون، فتضمين عامل خدمة بأبسط المزايا داخل الموقع سيوفر في هذه الحالة سرعة ومرونة استخدام الموقع في المناطق ذات جودة الاتصالات الضعيفة. اعتمد أول عامل خدمة أضيف إلى الموقع -سنشير إليه لاحقًا بعامل الخدمة "الأساسي standard"- على ثلاث استراتيجيات للتخزين المؤقت: التخزين المؤقت المسبق لملفات جافاسكريبت والتنسيقات الموروثة CSS لجميع الصفحات عند تثبيت عامل الخدمة بعد إطلاق حدث التحميل load للنافذة. تخديم الملفات الثابتة static من مخزن التخزين المؤقت CacheStorage عند توافرها، فإذا لم تتوافر فستُجلب من الشبكة، ثم تخزَّن تخزينًا مؤقتًا لتُخدم عند الزيارات اللاحقة للموقع. تخديم ملفات HTML من الشبكة أولًا، ثم تخزينها في مخزن التخزين المؤقت CacheStorage، وإذا لم يتوافر الاتصال بالشبكة في الزيارات اللاحقة للموقع فسيُخدم ملف HTML المطلوب من التخزين المؤقت. الاستراتيجيات السابقة ليست مميزةً أو جديدةً، وهي تقدم الفائدتين التاليتين: إمكانية العمل بدون الاتصال بالشبكة، وهو أمر مفيد في حالات الاتصال الضعيف بالشبكة. رفع أداء تخديم الملفات الثابتة بشكل كبير. أدى رفع الأداء هذا إلى تحسن بنسبة 42% و 48% لكل من المؤشرين أول طباعة للمحتوى First Contentful Paint، واختصارًا FCP، وأكبر طباعة للمحتوى Largest Contentful Paint، واختصارًا LCP، وهذه الأرقام مبنية على مراقبة المستخدم الحقيقية RUM. ما يعني أن تلك المكاسب ليست نظريةً فقط، بل هي تحسن حقيقي لأشخاص واقعيين. يوضح هذا المخطط مدة الطلب/الجواب لأدوات المطور في جوجل كروم، والطلب الموضح هو لملف ثابت من مخزن التخزين المؤقت CacheStorage، حيث استغرق عامل الخدمة 23 ميلي ثانية فقط لتحميل هذا الملف، بسبب عدم الحاجة للاتصال بالشبكة، وإمكانية تحميله من CacheStorage مباشرةً. تحسن الأداء هو نتيجة تجاوز الاتصال بالشبكة كليًا للملفات الثابتة الموجودة مسبقًا في CacheStorage، خصوصًا ملفات التنسيق المعيقة للتصيير، يمكن تحقيق تحسن شبيه بالأداء السابق بالاعتماد على التخزين المؤقت لطلبات HTTP، وسنلاحظ التشابه من حيث الأداء السابق مع FCP و LCP دون الاعتماد على عامل الخدمة نهائيًا. قد تتساءل عن الفرق إذًا بين CacheStorage والتخزين المؤقت لطلبات HTTP، يكمن الفرق في أن التخزين المؤقت لطلبات HTTP يحتاج -على الأقل في بعض الحالات- لإرسال طلب إلى الخادم للتحقق من حداثة الملف الموجود في التخزين المؤقت، ويمكن حل هذه المشكلة باستخدام القيمة immutable للترويسة Cache-Control، لكن ليس لها دعم واسع حاليًا، ويوجد حل آخر بتعيين قيمة عمرية كبيرة للملفات في max-age، لكن المزيج بين الواجهة البرمجية لعامل الخدمة وCacheStorage يوفر مرونةً أكبر. نستنتج مما سبق أن أبسط تضمين لعامل الخدمة يمكن أن يقدم تحسينًا في الأداء، وربما أفضل مما توفره ترويسة Cache-Control، ويمكن لعامل الخدمة أيضًا توفير مزايا واحتمالات أكبر، وهذا ما سنشاهده في هذا المقال. عامل خدمة أسرع وأفضل ليس إنشاء أطر عمل وأنماط جديدة نتبعها نحن المطورون هو الابتكار الحقيقي في عالم الويب، وإنما فائدة هذه الأدوات التي نستعملها بالنسبة للمستخدم الحقيقي لمنتجات تلك الأدوات، إذ يجب أن يكون المستخدم على رأس أولويات المطورين. توفر الواجهة البرمجية لعامل الخدمة مساحة ابتكار واسعة نسبيًا، تؤدي لأثر كبير على تجربة الويب، ويمكن لبعض الأمور، مثل التحميل المسبق للتنقل ومجرى القراءة ReadableStream، أن تحول عامل الخدمة من أمر جيد إلى سيء، يمكن باستخدام تلك المزايا توفير الإمكانيات التالية على الترتيب: تقليص وقت استجابة عامل الخدمة عبر تمكين العمل على التوازي بين وقت إقلاع عامل الخدمة وإرسال طلبات التنقل. التحكم في تدفق بيانات المحتوى القادم من CacheStorage والشبكة. وسندمج هذه الإمكانيات للحصول على ميزة جديدة، وهي التخزين المؤقت المسبق لأجزاء الترويسة والتذييل، ثم دمجها مع جزئيات من المحتوى القادم من الشبكة، مما سيقلل من كمية البيانات التي سنحتاج لتحميلها عبر الشبكة، وسيحسن السرعة المدرَكة للموقع في الزيارات المتكررة، ويندرج كل ما سبق تحت تصنيف الابتكار الحقيقي الذي يفيد الجميع. تحضير الأساسيات تبدو فكرة تجميع أجزاء الترويسة والتذييل في الموقع مع المحتوى القادم من الشبكة شبيهةً بالتطبيقات أحادية الصفحة Single Page Application، واختصارًا SPA، فهي مثلها ستحتاج لتطبيق نموذج "صدفة التطبيق app shell" على موقعك، لكن بدلًا من موجّه من طرف العميل يحاول تجميع المحتوى في قطعة صغيرة واحدة من الترميز، يجب أن تتصور الموقع مثل ثلاث قطع منفصلة: الترويسة المحتوى التذييل سيبدو ذلك بالشكل التالي في موقع الشركة: يوضح هذا المخطط ترميزًا لونيًا لأجزاء موقع شركة ويكلي تيمبر، حيث يخزَّن كل من الترويسة والتذييل ضمن CacheStorage، بينما يُجلب المحتوى عبر الشبكة، إلا إذا كان المستخدم غير متصل بالإنترنت. من الجدير بالذكر هنا أن تلك الأجزاء ليس ترميزها صحيحًا بالضرورة، أي ليس من الضروري أن تكون كل الوسوم مغلقةً ضمن كل جزئية على حدة، المهم فقط أن تنتج تركيبة هذه الجزئيات مع بعضها ترميزًا صحيحًا. سنبدأ أولًا بالتخزين المؤقت لقسمي الترويسة والتذييل عند تثبيت عامل الخدمة، تخدَّم هذه الأجزاء في موقع الشركة في المسارات partial-header/ وpartial-footer/: self.addEventListener("install", event => { const cacheName = "اسم للتخزين المؤقت هنا"; const precachedAssets = [ "/partial-header", // جزئية الترويسة "/partial-footer", // جزئية التذييل // ملفات أخرى نريد تخزينها تخزينًا مؤقتًا ]; event.waitUntil(caches.open(cacheName).then(cache => { return cache.addAll(precachedAssets); }).then(() => { return self.skipWaiting(); })); }); يجب أن نكون قادرين على جلب محتوى كل صفحة دون الترويسة والتذييل وكذلك معهما، وهذا ضروري لأن عامل الخدمة لن يتحكم بأول زيارة للموقع، لكن عندما يتولى عامل الخدمة يمكننا جلب جزئية المحتوى وتجميعها ضمن استجابة كاملة للصفحة مع الترويسة والتذييل من CacheStorage. إذا كان موقعك ذا محتوى ثابت، فذلك يعني توليد العديد من جزئيات الترميز التي يمكنك إعادة كتابة طلباتها في حدث عامل الخدمة ()fetch، أما إذا احتوى موقعك واجهةً خلفيةً -كما حال موقع الشركة في مثالنا- فيمكنك استخدام ترويسة طلب HTTP لتحدد للخادم ما إذا كنت تريد صفحةً كاملةً أم أجزاء المحتوى فقط. القسم الأصعب لدينا هو تجميع القطع معًا، وهو ما سنفعله الآن. تجميع القطع مع بعضها تعَد كتابة عامل خدمة بسيط تحديًا، لكن الأمور ستتعقد بسرعة عند محاولتنا تجميع عدة استجابات معًا، وأحد أسباب ذلك هو أننا سنحتاج لإعداد التحميل المسبق للتنقل لتجاوز الوقت اللازم لإقلاع عامل الخدمة. تضمين التحميل المسبق للتنقل يعالج التحميل المسبق للتنقل navigation preload مشكلة الوقت اللازم لإقلاع عامل الخدمة، وهو السبب في تأخير طلبات التنقل إلى الشبكة، ولا نريد من عامل الخدمة أن يؤثر على أداء الموقع. يجب تفعيل التحميل المسبق للتنقل صراحةً، لن يؤخر عامل الخدمة بعد تفعيله طلبات التنقل خلال إقلاعه، ويمكن تفعيل التحميل المسبق للتنقل ضمن حدث عامل الخدمة activate كالتالي: self.addEventListener("activate", event => { const cacheName = "اسم للتخزين المؤقت هنا"; const preloadAvailable = "navigationPreload" in self.registration; event.waitUntil(caches.keys().then(keys => { return Promise.all([ keys.filter(key => { return key !== cacheName; }).map(key => { return caches.delete(key); }), self.clients.claim(), preloadAvailable ? self.registration.navigationPreload.enable() : true ]); })); }); يجب أن نتحقق من توفر الميزة بسبب عدم الدعم الواسع للتحميل المسبق للتنقل، وهو ما فعلناه في المثال السابق ،وخزّنا نتيجته في المتغير preloadAvailable. بالإضافة لاحتياجنا استخدام ()Promise.all لجلب عدة عمليات غير متزامنة قبل أن تفعيل عامل الخدمة، من تلك العمليات تنظيف بيانات التخزين المؤقت القديمة، وانتظار كلٍ من()clients.claim -وهي التي تخبر عامل الخدمة بالتحكم حالًا بدلًا من انتظار عملية التنقل القادمة- وعملية تفعيل التحميل المسبق للتنقل. استخدمنا المعامل الثلاثي عند تفعيل التحميل المسبق للتنقل في المتصفحات التي توفر دعمًا له، وذلك لتجنب رمي الاستثناءات في المتصفحات التي لا تدعم تلك الميزة، ونفعل التحميل المسبق للتنقل إذا كانت قيمة preloadAvailable هي true، أما إن لم تكن كذلك فنمرر قيمةً منطقية بوليانيةً لا تؤثر على قبول التابع ()Promise.all. عند تفعيل التحميل المسبق للتنقل، داخل معالج الحدث ()fetch في عامل الخدمة لدينا، يجب أن نكتب شيفرةً تستفيد من جواب الطلب الذي سبق تحميله: self.addEventListener("fetch", event => { const { request } = event; // تم اختصار شيفرة معالجة الملفات الثابتة للتوضيح // ... // التحقق فيما إذا كان الطلب لمستند if (request.mode === "navigate") { const networkContent = Promise.resolve(event.preloadResponse).then(response => { if (response) { addResponseToCache(request, response.clone()); return response; } return fetch(request.url, { headers: { "X-Content-Mode": "partial" } }).then(response => { addResponseToCache(request, response.clone()); return response; }); }).catch(() => { return caches.match(request.url); }); // سنضيف المزيد هنا... } }); مع أن هذه ليست الشيفرة الكاملة للحدث ()fetch لعامل الخدمة، إلا أن فيها ما يحتاج الشرح: يُتاح الجواب المحمّل مسبقًا في المتغير event.preloadResponse، وستكون تلك القيمة undefined في المتصفحات التي لا تدعم التحميل المسبق للتنقل، لذا يجب تمرير event.preloadResponse للتابع ()Promise.resolve لتجنب مشاكل التوافقية تلك. بحسب ناتج الدالة then، إذا كان event.preloadResponse مدعومًا فسنستخدم الجواب المحمّل مسبقًا ونضيفه إلى CacheStorage عبر استدعاء الدالة المساعدة ()addResponseToCache، أما إن لم يكن مدعومًا فسنرسل طلبًا عبر الشبكة لجلب جزئية المحتوى عبر طلب ()fetch، بتعيين الترويسة المخصصة X-Content-Mode بالقيمة partial. إذا كان الاتصال بالشبكة غير متوفر حاليًا، فنعيد آخر نسخة من جزئية محتوى خُزنت في CacheStorage. نُعيد الجواب -بغض النظر عن مصدره- ونعينه قيمةً للمتغير networkContent الذي سنستخدمه لاحقًا. عندما يفعَّل التحميل المسبق للتنقل، ستضاف الترويسة Service-Worker-Navigation-Preload بالقيمة true إلى طلبات التنقل، وسنتحقق في النظام الخلفي من هذه الترويسة لإرجاع جزئية المحتوى فقط بدلًا من ترميز الصفحة كاملًة. لا يتوفر الدعم للتحميل المسبق للتنقل على جميع المتصفحات، لذا سنرسل ترويسةً مختلفةً في تلك الحالات، فسنستخدم في حالة موقع شركة ويكلي تيمبر ترويسةً مخصصةً بالاسم X-Content-Mode، وسنعين الثوابت التالية في الواجهة الخلفية للموقع: <?php // التحقق فيما إذا كان هذا طلب تنقل مسبق define("NAVIGATION_PRELOAD", isset($_SERVER["HTTP_SERVICE_WORKER_NAVIGATION_PRELOAD"]) && stristr($_SERVER["HTTP_SERVICE_WORKER_NAVIGATION_PRELOAD"], "true") !== false); // التحقق فيما إذا كان هذا طلب صريح لجزئية المحتوى define("PARTIAL_MODE", isset($_SERVER["HTTP_X_CONTENT_MODE"]) && stristr($_SERVER["HTTP_X_CONTENT_MODE"], "partial") !== false); // إذا كان أحد الحالتين صحيحًا فالطلب هو لجزئية المحتوى define("USE_PARTIAL", NAVIGATION_PRELOAD === true || PARTIAL_MODE === true); ?> يمكن بعد ذلك الاستعانة بقيمة الثابت USE_PARTIAL لتحديد نوعية الجواب: <?php if (USE_PARTIAL === false) { require_once("partial-header.php"); } require_once("includes/home.php"); if (USE_PARTIAL === false) { require_once("partial-footer.php"); } ?> إذا كنت تستخدم التخزين المؤقت لصفحات HTML، فيجب عليك تعيين قيمة للترويسة Vary لأجوبة طلبات HTML لتؤخَذ الترويسة Service-Worker-Navigation-Preload، وفي مثالنا أيضا الترويسة X-Content-Mode للتخزين المؤقت لطلبات HTML بالحسبان، وقد لا تحتاج لذلك إذا لم تستخدم التخزين المؤقت لـ HTML في مشروعك. بعد أن انتهينا من معالجة التحميل المسبق للتنقل، سننتقل الآن إلى تدفق بيانات أجزاء المحتوى عبر الشبكة وتجميعها مع أجزاء الترويسة والتذييل من CacheStorage داخل استجابة موحّدة يوفرها عامل الخدمة. تدفق بيانات أجزاء المحتوى وتجميع ردود الطلبات يتوافر كل من الترويسة والتذييل مباشرةً لأنهما موجودان داخل CacheStorage منذ تثبيت عامل الخدمة، لكن ما سيعيقنا هو جزئية المحتوى التي سنحتاج لجلبها عبر الشبكة، لذا من الضروري أن نرسل أو نبث الاستجابة على شكل تدفق لنستطيع إضافة المحتوى تباعًا حال وصوله بأسرع ما يمكن، ويمكننا الاستفادة من ReadableStream لتحقيق ذلك. يجب الانتباه عند التعامل مع ReadableStream، فقد ينتهي الأمر بالتأثير على الأداء بدل تحسينه إذا أغفلنا بعض الخطوات الهامة، وسيكون التابع الذي يجمع الطلبات معًا كالتالي: async function mergeResponses (responsePromises) { const readers = responsePromises.map(responsePromise => { return Promise.resolve(responsePromise).then(response => { return response.body.getReader(); }); }); let doneResolve, doneReject; const done = new Promise((resolve, reject) => { doneResolve = resolve; doneReject = reject; }); const readable = new ReadableStream({ async pull (controller) { const reader = await readers[0]; try { const { done, value } = await reader.read(); if (done) { readers.shift(); if (!readers[0]) { controller.close(); doneResolve(); return; } return this.pull(controller); } controller.enqueue(value); } catch (err) { doneReject(err); throw err; } }, cancel () { doneResolve(); } }); const headers = new Headers(); headers.append("Content-Type", "text/html"); return { done, response: new Response(readable, { headers }) }; } أهم ما في التابع السابق: يقبل التابع ()mergeResponses الوسيط responsePromises، وهو مصفوفة تحوي كائنات من النوع Response، نحصل عليها إما من التحميل المسبق للتنقل أو ()fetch أو ()caches.match، وبفرض وجود اتصال بالشبكة ستحوي المصفوفة دومًا على ثلاث أجوبة، اثنان من ()caches.match وواحد من الشبكة. قبل أن نرسل الاستجابات داخل المصفوفة responsePromises، يجب أن نربط كل استجابة منها بقارئ واحد، يُستخدم لاحقًا في باني ()ReadableStream ليرسل محتوى كل استجابة منها. نُنشئ وعدًا Promise بالاسم done، نعين داخله تابعي الوعد ()resolve و ()reject للمتغيرات الخارجية doneResolve وdoneReject على التوالي، سيُستخدم المتغيران داخل ()ReadableStream للإشارة إلى نجاح تدفق البيانات من عدمه. تُنشأ النسخة الجديدة من ()ReadableStream بالاسم readable، وعندما تُرسل الاستجابات على شكل تدفق من CacheStorage والشبكة، سيضاف محتوى كل استجابة إلى readable. سيرسل التابع ()pull محتوى أول استجابة في المصفوفة على شكل تدفق، وإذا لم يُلغَ تدفق البيانات لسبب ما، فسيُتجاهل قارئ كل استجابة عبر استدعاء التابع ()shift في مصفوفة الاستجابات حالما ينتهي تدفق بيانات المحتوى كليًا، نكرر هذا الأمر إلى أن لا يبق أي قارئ في المصفوفة. سيُرجع تدفق بيانات الاستجابات المدموجة في استجابة واحدة، وسيُعاد مع الترويسة Content-Type بالقيمة text/html. توجد طريقة أبسط لذلك وهي استخدام TransformStream، لكنها لا تُدعم في جميع المتصفحات، لذا سنعتمد حاليًا هذه الطريقة. لنعد الآن إلى الحدث ()fetch في عامل الخدمة الذي كتبناه سابقًا، ونطبق داخله التابع ()mergeResponses: self.addEventListener("fetch", event => { const { request } = event; // تم اختصار شيفرة معالجة الملفات الثابتة للتوضيح // ... // التحقق فيما إذا كان الطلب لمستند if (request.mode === "navigate") { // تم اختصار شيفرة التحميل المسبق/الجلب من الشبكة. // ... const { done, response } = await mergeResponses([ caches.match("/partial-header"), networkContent, caches.match("/partial-footer") ]); event.waitUntil(done); event.respondWith(response); } }); عند نهاية معالج الحدث ()fetch نمرر جزأي الترويسة والتذييل من CacheStorage إلى التابع ()mergeResponses، ونمرر النتيجة إلى تابع الحدث ()fetch، واسمه ()respondWith، الذي يخدم الاستجابة المدموجة نيابةً عن عامل الخدمة. النتائج النهائية نفذنا بالكثير من العمل المعقد والصعب نسبيًا، وقد لا يكون هذا الحل مناسبًا لبنية موقعك، لذا من المهم معرفة هل يعوض تحسن الأداء الناتج ذلك الجهد المبذول، وقد كانت مكاسب الأداء جيدةً في حالة موقع شركة ويكلي تيمبر: يظهر المخطط القيم الوسطية لكل من FPC و LCP لعدة أنواع من عامل الخدمة لموقع ويكلي تيمبر. يقيس اختبار المحاكاة الأداء ضمن جهاز محدد وجودة اتصال معينة بالشبكة، وقد أجري الاختبار السابق على نسخة تجريبية من الموقع بمحاكاة لهاتف أندرويد نوكيا 2 واتصال "3G سريع" مخنوق داخل أدوات المطور في كروم، واختُبرت كل فئة عشر مرات على الصفحة الرئيسية للموقع، ونستنتج من ذلك ما يلي: لا يوجد عامل خدمة أبدًا أسرع قليلًا من عامل الخدمة الأساسي الذي يستعمل طرائق بسيطة في التخزين المؤقت، وكلاهما أبطأ من عامل الخدمة الذي يبث البيانات، وقد يعود ذلك إلى عملية بدء عامل الخدمة مع ذلك ذلك ستظهر بيانات RUM (مراقبة المستخدم الحقيقية) التي سأعرضها بعد قليل حالة مختلفة. عبد اللطيف ايمش: لم أفهم شيئًا منها يرتبط كل من LCP و FCP ببعضهما عند عدم استخدام عامل خدمة، أو استخدام عامل خدمة "أساسي"، بسبب كون محتوى الصفحة بسيطًا وتنسيقات CSS صغيرةً للغاية، حيث تكون LCP عادةً الفقرة الافتتاحية داخل الصفحة. تفصل خدمة تدفق البيانات داخل عامل الخدمة FCP عن LCP، لأن جزئية الترويسة تُرسل مباشرةً من CacheStroage. تنقص قيمة كل من FCP وLCP عند تدفق البيانات داخل عامل الخدمة مقارنةً بالحالات الأخرى. يظهر المخطط القيم الوسطية لكل من FPC و LCP في بيانات الأداء في RUM (مراقبة المستخدم الحقيقي) لعدة أنواع من عامل الخدمة لموقع ويكلي تيمبر. تظهر فائدة تدفق البيانات في عامل الخدمة لدى المستخدمين الحقيقيين، حيث لوحظ تحسن بقيمة 79% لقيمة FCP مقارنةً بعدم استخدام عامل خدمة أبدًا، وتحسن بقيمة 63% عن استخدام عامل الخدمة "الأساسي"، وقد تحسن الأداء في قيمة LCP أقل من ذلك، حيث لوحظ تحسن كبير بقيمة 41% مقارنةً بعدم استخدام عامل خدمة أبدًا، لكن كانت القيمة أبطأ قليلًا مقارنةً مع استخدام عامل الخدمة "الأساسي". من المهم النظر إلى النسبة الكبيرة من بيانات الأداء المتوفرة، ولا يكفي النظر إلى المتوسطـ، لننظر إلى نسبة 95% من بيانات أداء FCP وLCP : مخطط لنسبة 95% من بيانات الأداء في RUM لكل من FCP و LCP لعدة أنواع من عامل الخدمة لموقع ويكلي تيمبر. البيانات السابقة هي أفضل مكان يمكننا من خلاله استنتاج أبطأ أداء، ويمكننا ملاحظة تحسن بنسبة 40% و51% عند استخدام تدفق بيانات المحتوى ضمن عامل الخدمة لكل من FCP وLCP على التوالي مقارنةً بعدم استخدام عامل الخدمة، كما نلاحظ انخفاضَا لهاتين القيمتين بقيمة 19% و 43% على التوالي مقارنةً بعامل الخدمة "الأساسي"، وقد تلاحظ أن هذه البيانات غريبة بعض الشيء عن بيانات المحاكاة السابقة، ويجب أن تتذكر أن بيانات RUM تعتمد على زوّار موقعك، وهم يستخدمون شبكات اتصال متعددةً وأجهزةً مختلفةً. استفاد كل من مؤشري FCP وLCP من الفوائد التي لا تحصى من فكرة تدفق بيانات المحتوى والتخزين المسبق -في حالة متصفح كروم-، والتخفيف من الترميز المرسل عبر الشبكة من خلال تجميع أجزاء الموقع من CacheStorage والشبكة، وأكبر مؤشر تأثر من ذلك هو FCP، يوضح الفيديو التالي الفروقات بين عدم استخدام عامل خدمة، وبين استخدام عامل الخدمة "الأساسي"، وبين استخدام تدفق البيانات والتخزين المسبق داخل عامل الخدمة: تظهر الفيديوهات الثلاثة اختبارًا للزيارة المتكررة للصفحة الرئيسية في موقع ويكلي تيمبر، على اليسار صفحة لا يتحكم بها عامل الخدمة، فقط التخزين المسبق لـ HTTP، وتظهر على اليمين صفحتان يتحكم بهما عامل الخدمة، مع استخدام CacheStorage. يمكننا أن نسأل أنفسنا الآن، بما أن هذه الطريقة حققت تحسن الأداء الكبير هذا مع موقع بسيط كهذا، فكيف سيكون التحسن مع المواقع الأكثر تعقيدًا، وماذا سنتوقع من موقع فيه قسم ترويسة وتذييل بحمولة ترميز أكبر من تلك؟ الخلاصة لعملنا السابق مساوئ بلا شك، فمثلًا وضع الترويسة في التخزين المؤقت يعني أنه يجب تحديث عنوان المستند من خلال جافاسكريبت عند كل انتقال عبر تغيير قيمة document.title، كما يجب تعديل حالة التنقل من خلال جافاسكريبت أيضًا لتعكس الصفحة الحالية إذا كنت تنفذ ذلك داخل موقعك، لاحظ أن ذلك لن يؤثر على فهرسة موقعك لأن بوت جوجل Googlebot يزحف إلى الصفحات دون أن يحوي تخزينًا مؤقتًا. قد تواجه تحديات أيضًا في المواقع التي تحوي على نظام مصادقة، فإذا كانت الترويسة داخل الموقع تظهر المستخدم الذي سجل الدخول حاليًا مثلًا، قد تحتاج لتحديث جزئية ترويسة الموقع الآتية من CacheStorage من خلال جافاسكريبت عند كل تنقّل لتعكس المستخدم الموثّق الحالي، ويمكنك ذلك مثلًا عبر تخزين بيانات أساسية عن المستخدم داخل localStorage، وتحديث الواجهة من تلك البيانات. ستواجه تحديات أخرى، وسيكون الأمر عائدًا إليك لتحديد المنافع التي سيحصل عليها عميلك مقابل كلفة تطويرها، وتناسب الطريقة التي عرضناها غالبًا مواقع، مثل المدونات، ومواقع التسويق، والمواقع الإخبارية، والمتاجر الالكترونية وغيرها، لكن كل ذلك يعتمد بالنهاية على تحسن الأداء والمردود التي ستحققه من جعل موقعك تطبيقًا بصفحة واحدة SPA، ويكمن الفرق أنك هنا لا تبدل طرق تنقل اختبرت عبر الزمن والمعاناة مع عواقب ذلك، لكنك تحسن تلك الطرق فقط، ويجب أخذ هذه الفكرة بعين الاعتبار في عالمنا الذي أصبح فيه التوجيه بطرف العميل منتشرًا. قد تتساءل "ماذا عن استخدام Workbox؟" وتساؤلك هذا في مكانه، حيث يبسط Workbox التعامل مع الواجهة البرمجية لعامل الخدمة، ولا خطأ في استخدامه، لكن يفضل دائمًا العمل مع عامل الخدمة مباشرةً، حيث سيكسبك ذلك خبرةً أكبر، وستتعرف على كيفية عمل Workbox أساسًا، لكن استخدام عامل الخدمة صعب بعض الشيء، لذا استعن بـ Workbox إذا كان يناسبك، فهو خيار جيد وأفضل من أطر العمل الأخرى. الواجهة البرمجية لعامل الخدمة أداة قوية لتقليل كمية الترميز المرسل عبر الشبكة، استفاد منها موقع شركة ويكلي تيمبر ومعظم المواقع التي توجهت لاستخدامه، فأصبح الموقع بسببه أسرع بكثير في أماكن بعيدة داخل ولاية ويسكونسون. ترجمة -وبتصرف- للمقال Now THAT’S What I Call Service Worker لصاحبه Jeremy Wagner. اقرأ أيضًا مفهوم Service Worker وتأثيره في أداء وبنية مواقع وتطبيقات الويب زيادة سرعة أداء المواقع باستخدام تقنية pre-fetching
-
يصف هذا المقال أداةً غايةً في الأهمية لتحليل أداء صفحات ويب فيما يتعلق بتنفيذ شيفرات HTML وCSS وجافاسكربت، وبالتالي سيكون المطوِّر قادرًا على تحديد النقاط السلبية في أداء الموقع والتي ستكون الهدف المناسب لعمليات التحسين والتطوير التالية. نظرة سريعة على الأداة Performance تلقي هذه الأداة الضوء على استجابة صفحات ويب عمومًا، وعلى أداء جافاسكربت وتخطيط الصفحة، كما تتيح هذه الأداة إنشاء تسجيلات أو ملفات أداء لصفحتك خلال فترة زمنية معينة، وتعرض لك لمحةً عامةً عن الأشياء التي نفّذها المتصفح لتصيير الصفحة من خلال تلك الملفات، ورسمًا بيانيًا عن حالة مكدس جافاسكربت مع الزمن من خلال المكوّن frame rate. مكونات الأداة Performance تقدِّم لك الأداة أربع أدوات جزئية لفحص ميزات ملف الأداء بتفاصيل أكثر: الأداة Waterfall: تعرض لك العمليات المختلفة التي ينفذها المتصفح مثل تنفيذ مخطط العمل وأداء جافاسكربت ومهام إعادة رسم الصفحة repaint وتجميع الموارد التي انتهى استخدامها Garbage Collection، أي ستساعدك في فهم ما ينفِّذه المتصفح عندما يتفاعل مع موقع ويب. الأداة Call Tree: تعرض دوال جافاسكربت التي تستغرق من المتصفح أكبر وقت في تنفيذها محددةً الاختناقات التي تحدث عند تنفيذ شيفرة جافاسكربت الخاصة بموقع الويب. الأداة Flame Chart: تعرض حالة مكدس استدعاءات جافاسكربت والدوال التي يجري تنفيذها ومتى خلال فترة تسجيل ملف الأداء. الأداة Frame Rate: تعرض حالة التجاوب العامة لموقعك مع مختلف الشاشات. الأداة Allocations: تعرض حالة كومة الذاكرة الناتج عن تنفيذ شيفرة جافاسكربت خلال زمن تسجيل ملف الأداء، ولن تظهر هذه الأداة إلا عندما تفعِّل خيار سجل حجوزات الذاكرة Record Allocations من خلال إعدادات الأداة Performance. سيناريوهات استخدام الأداة Performance يمكن استخدام أدوات جزئية محددة أو أكثر لمراقبة حالات محددة نذكر منها: متابعة الحركات الناتجة عن استخدام خصائص CSS: استخدم أداة Waterfall لفهم الآلية التي يُحدِّث فيها المتصفح صفحة ويب وتأثير الحركات التي تنتج عن تغير قيم خصائص CSS على الأداء. الاستخدام المكثَّف لجافاسكربت: استخدام الأداتين frame rate وWaterfall وللاطلاع على مشاكل الأداء الناتجة عن تنفيذ شيفرة جافاسكربت وكيف يساعد استخدام عمّال ويب web workers في حالات مثل هذه. واجهة مستخدم الأداة Performance تتألف واجهة المستخدِم من أربعة أقسام رئيسية: شريط الأدوات Toolbar. لوحة التسجيلات Recordings pane. لوحة نظرة عامة Recording overview. لوحة التفاصيل Details pane والتي قد تعرض أيًا من: تفاصيل الأداة الجزئية Waterfall. تفاصيل الأداة الجزئية Call Tree. تفاصيل الأداة الجزئية Flame Chart. شريط الأدوات يضم شريط الأدوات أزررًا مهمتها ما يلي: تشغيل وإيقاف عملية تسجيل ملف الأداء. إدراج ملف أداء مخزن سابقًا. مسح لوحة السجلات، وانتبه أنك ستفقد أية سجلات غير مخزّنة إذا فعلت ذلك. ترشيح العلامات markers التي تُعرض عند استخدام الأداة الجزئية Waterfall. الانتقال بين تفاصيل الأدوات الجزئية في لوحة التفاصيل. الوصول إلى نافذة الإعدادات المنبثقة. لوحة التسجيلات تعرض هذه اللوحة جميع التسجيلات التي تحمّلها، بما في ذلك ما سجّلته في هذه الجلسة وما استوردته من تسجيلات سابقة. يُعرَض تسجيل واحد فقط وتصطف بقية التسجيلات على هيئة قائمة ضمن الأداة، كما يمكنك اختيار أيّ تسجيل لعرضه بالنقر عليه؛ أما لتخزين التسجيل على صورة ملف JSON، فانقر على زر حفظ Save. لوحة النظرة العامة تعرض لمحة عامة عن التسجيل بأكمله مع الزمن الذي يمثله المحور X، كما تحوي اللوحة عنصرين هما لمحة عامة عن الأداة Waterfall ورسم بياني لمعدل الإطارات frame rate. لمحة عامة عن الأداة Waterfall تتضمن عرضًا مصغّرًا عن الأداة Waterfall وتُمثِّل العمليات المُسجَّلة وفق نظام لوني مشابه للمخطط المعتمد في الأداة Waterfall الرئيسية. الرسم البياني لمعدل الإطارات تعطيك لمحةً عامةً عن استجابة المتصفح خلال فترة التسجيل، كما يمكنك الاطلاع على المقال المكوّنات الرئيسية للأداة Performance لمعلومات أكثر. ترابط الأحداث يمكنك ربط الأحداث بين العنصرين السابقين طالما أنهما متزامنان، فإذا نظرنا مثلًا إلى لقطة الشاشة التي نعرضها تاليًا، فستلاحظ أنّ عملية رسم مطوّلة لصفحة ويب، والتي تظهر على أساس شريط أخضر في العرض المصغّر للأداة Waterfall يقابلها انخفاض في معدل الإطارات. نظرة أقرب إلى العرض يمكنك اختيار شريحة من عرض النظرة العامة للتسجيل لتفحص تفاصيله، فعندما تختار شريحةً ما، فسيتغير محتوى لوحة التفاصيل لتحتوي فقط على تفاصيل عن الشريحة التي اخترتها، ولاحظ في لقطة الشاشة التالية انخفاض معدل الإطارات في الشريحة المقابل لعملية الرسم الطويلة لصفحة الويب بتفاصيل أكثر. لوحة التفاصيل تعرض تفاصيل الأداة الجزئية التي تختارها، كما يمكنك الانتقال من أداة إلى أخرى عبر الأزرار في شريط الأدوات. الأداة Waterfall تقدِّم الأداة عرضًا عن العمل الذي ينفذه المتصفح خلال فترة التسجيل مثل تنفيذ شيفرة جافاسكربت، وتحديث تنسيق الصفحة ومخططها وتنفيذ عمليات إعادة رسم الصفحة، كما يمثِّل المحور X زمن التسجيل وتتعاقب العمليات المسجلة على هيئة شلال لتعكس الطبيعة التسلسلية لآلية تنفيذ الشيفرة في المتصفح. الأداة Call Tree تمثِّل محللًا للعينات يأخذ بياناته من تنفيذ شيفرة جافاسكربت لصفحة الويب، إذ تأخذ الأداة عينات دوريًا من محرك جافاسكربت وتسجِّل بيانات عن الشيفرة التي تُنفّذ لحظة التقاط العينة، كما يتعلق عدد العينات التي تلتقط عند تنفيذ دالة محددة بالزمن المستغرق لتنفيذها، وبالتالي ستكون قادرًا على تحديد الاختناقات في شيفرتك. الأداة Flame chart تخبرك هذه الأداة عن حالة مكدس الاستدعاءات في كل لحظة من لحظات التسجيل. الأداة Allocations تشابه هذه الأداة الجديدة في فايرفوكس 46 الأداة Call Tree لكن لمواقع حجز الذاكرة، إذ تعرض لك الدوال التي تحجز ذاكرةً أكبر خلال فترة تسجيل ملف الأداء، ولن تظهر هذه الأداة إلا عندما تفعّل خيار سجِّل حجوزات الذاكرة Record Allocations من خلال إعدادات الأداة Performance. لمعلومات أكثر عن الأدوات الجزئية اطلع على المقال المكوّنات الرئيسية للأداة Performance. التعامل مع الأداة Performance إليك بعض الإرشادات للتعامل مع الأداة Performance تشغيل الأداة لتشغيل الأداة: اضغط المفتاحين Shift + F5 اختر Performance من القائمة الفرعية أدوات مطوري ويب Web Developer الموجودة ضمن قائمة فايرفوكس أو قائمة الأدوات Tools، وهذا إذا كنت تعرض شريط القائمة أو كانت على نظام ماك أو إس OS X. اختر Performance من زر الأدوات في شريط الأدوات إذا كان موجودًا على متصفحك. تسجيل ملف أداء انقر على أيقونة الساعة في لوحة التسجيلات لبدء التسجيل وانقرها مجددًا لإيقافه، كما يمكنك بدء وإيقاف التسجيل من خلال الأداة Web Console باستخدام الأمرَين ()console.profile و()console.profileEnd. حفظ ملف أداء انقر على الرابط الذي يحمل العنوان "حفظ Save" إلى جوار التسجيل في لوحة التسجيلات. تحميل ملف أداء انقر على زر استيراد Import ثم اختر الملف الذي تريد استيراده. حذف جميع الملفات المدرجة انقر على أيقونة سلة المهملات أو على زر Clear وانتبه إلى أنك ستفقد أية سجلات غير مخزّنة إذا فعلت ذلك. اختيار أداة انقر على الزر الموافق للأداة ضمن شريط الأدوات. اختيار العلامات المعروضة اضغط على زر المرشح Filter في شريط الأدوات لاختيار العلامات التي تريد إظهارها في الأداة Waterfall. إلقاء نظرة أقرب على الأداء اختر شريحةً محددةً من لوحة النظرة العامة للتسجيل وستعرض تفاصيل هذه الشريحة في لوحة التفاصيل. ترجمة -وبتصرف- للمقالات التالية: ?What tools are available to debug and improve website performance. ?How to Open the Performance tools. UI Tour. اقرأ أيضًا تحسين الظهور في محركات البحث HTML و CSS للمبتدئين: كيف تصمم أول صفحة ويب لك
-
يعد التسويق عبر البريد الإلكتروني من أكثر أقنية التسويق فعالية وربحًا وفقًا لقيمة عائد الاستثمار ROI، حيث يشير إلى 44 دولار أمريكي لكل دولار جرى إنفاقه. ومن العوامل التي تزيد من قوة التسويق عبر البريد الإلكتروني هو القدرة الكبيرة على توجيه عملية التسويق نحو أشخاص محددين Personalization. لهذا سنناقش في مقالنا كتابة قائمة تحقق ناجحة عندما نوجّه التسويق عبر البريد الإلكتروني. لكن بداية، ما هو التسويق الموجّه عبر البريد الإلكتروني؟ شرح مضمون التسويق الموجه عبر البريد الإلكتروني تتعدى فكرة التوجيه (أو التخصيص) في التسويق عبر البريد الإلكتروني مجرد ذكر اسم مستقبل الرسالة عندما تحييه في بدايتها، فهو في جوهره التوجه إلى كل متلقٍ شخصيًا. وبالطبع سيتضمن ذلك مخاطبته باسمه ويتعداه إلى تزويده بالمحتوى الذي يلائمه وتقديم تجربة فريدة في التعامل مع كل مشترك. كيف تحقق ذلك؟ البيانات هي أداتك الرئيسية ستحتاج إلى كم كبير من المعلومات عن عملائك لكي تتمكن من إنشاء محتوى مناسب لهم. نذكر من هذه المعلومات: الاسم الأول. سلوكه سابقًا ضمن موقعك. موقعه الجغرافي. تاريخ المشتريات التي نفّذها. إذ تعتمد البيانات التي تحتاجها لتقديم تجربة خاصة لعملائك على المنتج ونموذج الأعمال وأهدافك التسويقية أساسًا. وستكون استراتيجيتك في التسويق الموجّه عبر البريد الإلكتروني أفضل كلما جمعت بيانات أكثر حول عملائك. حاول أن تجمع قدر ما تستطيع من المعلومات عن عملائك لحظة اشتراكهم في موقعك إن أمكن. إذ يسهل ذلك تنفيذ حملات تسويقية موجّهة لاحقًا. تجزئة قوائم المشتركين أمر أساسي جزئ قائمة المشتركين وفقًا للبيانات التي حصلت عليها بوضع العملاء الذين يتشاركون بعض الصفات في مجموعة واحدة. فيمكنك مثلًا إنشاء مجموعاتٍ بناء على الموقع الجغرافي أو الجنس أو المواقع التي تصفحوها. ولا بد من استخدام التجزئة المتقدمة إن كان ذلك ممكنًا، واستخدم عدة صفات معًا لتحسين أسلوب التجزئة بحيث تحقق مستوى أفضل من ناحيتي توجيه التسويق واستهداف العملاء. فالتجزئة طريقة رائعة لإنشاء محتوى يتعلق بميول مشتركيك دون الحاجة إلى كتابة بريد إلكتروني لكل عميل على حدى. اعتمد الأتمتة لن يقلع التسويق الموجّه عبر البريد الإلكتروني إن لم تكن عملية التسويق آلية. فهناك العديد من الحيثيات المتغيرة التي تؤثر في نجاح الحملة وتصعب إدارتها يدويًا، سواء أكانت قائمة البريد الإلكتروني لديك صغيرة أم كبيرة. أهمية توجيه وتخصيص التسويق عندما سئل المسوقين عن أكثر الأولويات أهمية في مضمار التسويق مستقبلًا، كان جواب 33% منهم "التسويق الموجّه". كما تحدث 74% من المسوقين عن دور التسويق الموجّه في زيادة انخراط العملاء وأشاروا إلى زيادة مقدارها 20% في المبيعات عند الاستفادة من التجارب الشخصية لعملائهم. لهذه الغاية شاركنا فريقًا من Moveable Ink لإنشاء قائمة التحقق الناجحة في التسويق الموجّه عبر البريد الإلكتروني، وذلك لمساعدة المسوقين على تسخير قوة التسويق الموجّه للوصول إلى الإنسان وليس إلى صناديق البريد وحسب. قائمة التحقق الناجحة في التسويق الموجه عبر البريد الإلكتروني لنتعمق أكثر في هذه القائمة. الخطوة 1: أنشئ استراتيجية خاصة بك لتوجيه البريد الإلكتروني الدراسة السلوكية: أنشئ محتوى البريد الإلكتروني ليعتمد على سلوك المشترك الحالي. حالة الطقس: أنشئ محتوى البريد الإلكتروني بحيث يأخذ في الحسبان حالة الطقس المحلي للمشترك. الصور: حاول أن تضيف اسم المشترك إلى صورة للفت انتباهه. الموقع: استفد من الموقع الجغرافي للمشترك لإنشاء ملاحظات تذكير مفيدة له أيًا كان هذا الموقع. الخطوة 2: راجع كل جزء من بريدك الإلكتروني سطر الموضوع: الناحية القواعدية: تحقق من صحة القواعد النحوية وأنّ أسلوب توجيه البريد في السياق الصحيح ضمن سطر الموضوع. النصوص الاحتياطية: حضر نصًا افتراضيًا في حالة عدم توفر البيانات على ملف. الطول: إجعل طول سطر الموضوع مناسبًا آخذًا في الحسبان حجم واجهة العرض. ما قبل الترويسة preheader: الطول: تحقق من الطول للتأكد من إمكانية القراءة على كل الأجهزة. الترويسة: الخط: إن استخدمت خطًا جديدًا أو مختلفًا في ترويسة البريد الإلكتروني المخصص فاحرص أن يتماشى مع بقية محتوى الرسالة. الاختبار: استخدم أداة مثل Litmus للاختبار. جسم الرسالة: الاختبار: وذلك إن كنت ستستخدم الخصوصية المتقدمة في إنشاء بريدك كما في الحالة التي يعتمد فيها المحتوى على سلوك المشترِك، اختبر مثلًا عدة تغييرات. القواعد: تحقق من القواعد النحوية والأخطاء الإملائية وكل ما يتعلق بذلك. التحولات: تأكد أن المحتوى المخصص الذي تكتبه سيقود المتابعين إلى إتخاذ القرار. اتخاذ القرار Call-to-action: التعقب: بما في ذلك تعقب الروابط لكي تتأكد من فعالية توجيهك للمحتوى. نسخة اتخاذ القرار CTA: اجعل نسختك التي تدفع لاتخاذ القرار مقنعة. الروابط: تأكد أن روابطك ستقود إلى الوجهة الصحيحة. الوضوح: تأكد أنّ المحتوى الذي يدفع لاتخاذ القرار واضح وسهل الإيجاد. الخطوة 3: تحقق من جميع هذه الخطوات النهائية والحيوية تحقق من حقول البيانات: هل جميع البيانات التي تحتاجها لكل حقل من الحقول المخصصة موجودة؟ إنّ جودة توجيه التسويق من جودة البيانات التي تمتلكها، لذا تحقق أكثر من مرة من حقول البيانات لتتأكد. فآخر ما تريد ظهوره في حقول البيانات أخطاء في كتابة أو صياغة عناوين الحقول. حضّر بيانات احتياطية: حضر محتوىً افتراضيًا لكل حقل من الحقول التي قد لا تنشر. ينبغي أن يكون المحتوى الافتراضي بريدًا إلكترونيًا يمكن أن يُرسل إلى أي من عملائك. اختر وقت الإرسال المثالي: قد يعرّض اختيار التوقيت الخاطئ بريدك الموجّه بعناية للخطر. راجع التصميم: تذكر أن تختبر أسماء بأطوال مختلفة، والمحارف الخاصة وتراصف الصور في نسختك من البريد الموجّه. أرسل لنفسك ولزميلك نسخة من البريد الموجّه فكلما كثرت العيون المراقبة كانت النتيجة أفضل. حضر اختبار موازنة A/B test: أرسل بريدين أحدهما موجّه والآخر عام، فهذا أفضل مقياس لاستراتيجيتك في توجيه أو تخصيص الرسائل. تأكد أن تصميمك متجاوب مع جميع الأجهزة: هل يبدو التصميم جيدًا على سطح المكتب أو الهاتف المحمول؟ تحقق من جودة التصميم على كل الأجهزة التي قد تستعرضه. تحضر للانطلاق يلعب توجيه البريد الإلكتروني دورًا رئيسيًا في تنفيذ الحملات الدعائية عبر البريد الإلكتروني التي سيجدها العملاء مناسبة ولا تقاوم وخاصة عندما يتخذون قرارًا بالشراء. لقد أنشأنا كمًا هائلًا من المصادر كي نساعدك في صقل مهارتك في التسويق الموجّه عبر البريد الإلكتروني. ترجمة -وبتصرف- للمقال Ultimate email marketing personalization checklist اقرأ أيضًا أهم الأفكار التي يجب أن تعرفها عن التسويق عبر البريد الإلكتروني القائمة البريدية: الوصفة السريّة لنجاح الشركات الناشئة كيف تحصل على قائمة بريد الكتروني مُتفاعلة لماذا يجب عليك أن تتجنب شراء القوائم البريدية الجاهزة كيف تربح المال من قائمتك البريدية؟
-
يعي المسوقون من جميع المستويات أنّ تجربة العملاء لن تؤثر على نسب المبيعات الأولية فقط بل تلعب دورًا مهمًا في المحافظة على العملاء. حيث تساهم أقنية تسوق مختلفة في نجاح إدارتك لتجربة العميل (اختصارًا CXM أو CEM). وعلى الرغم من أنّ تحديد القناة الأفضل لك قد يستغرق بعض الوقت، فقد اكتشف المسوقون أهمية التسويق عبر البريد الإلكتروني في تعزيز تجربة العملاء ووجدوا أنه: يفضل العملاء متابعة مستجدات علاماتهم التجارية المفضلة من خلال البريد الإلكتروني موازنة بغيره من قنوات التسويق بما في ذلك وسائل التواصل الاجتماعي والتطبيقات. يعطي التسويق الإلكتروني أعلى قيمة لعائد الاستثمار الكلي موازنة بأية قنوات أخرى. من الحيوي أن نمتلك أرضية جيدة في فهم إدارة تجربة العملاء قبل الغوص في ميزات التسويق عبر البريد الإلكتروني في إدارة هذه التجربة وكيف ستؤثر على أعمالك. ماهي إدارة تجربة العملاء؟ يغطي مفهوم إدارة تجربة العملاء ما هو أعمق من فكرة العملاء السعداء، ووفقًا لموقع Gartner فهو تطبيق عملي للتصاميم ومن ثم التعامل مع ردود أفعال العملاء. إنّ الهدف الرئيسي لهذه الممارسة هو الوصول إلى مستوى توقع العملاء وحتى تجاوزه. سيقود ذلك عندها إلى رضا وقناعة أكبر للعملاء ومزيدًا من الولاء والمناصرة. لقد نفذنا مؤخرًا دراسة عن حالة الأعمال الصغيرة، حيث سألنا عن أفضل بيئتين ترغب العلامات التجارية في التركيز عليها بشدة خلال العام 2019 فكان الجواب الحصول على عملاء جدد والاحتفاظ بالعملاء الحاليين. ولزيادة عدد العملاء الجدد والمحافظة على الحاليين، لا بدّ أن يعمل فريقك من المسوقين بعناية في فريق خدمة العملاء لتطوير أساليب التواصل بحيث ترتقي إلى تطلعات الجمهور وتتجاوزها. وهنا يظهر دور إدارة تجربة العملاء على كلا الصعيدين الرقمي والفيزيائي أي خدمة العملاء عبر الإنترنت وضمن المتاجر وخاصة لزوار الأسواق الشعبية وأكشاك الأرصفة. ستجد تنوعًا في الأدوات المتاحة للعلامات التجارية في إدارة تجربة العملاء. وليس من الضروري إنفاق مبالغ كبيرة على برمجيات مختلفة تساعدك في وضع خطة للتحرك، إذ يمكنك كبديل أن تركز على عدة نواحي مفتاحية بما في ذلك: معرفتك بالفئة المستهدفة من الجمهور. مسيرة العملاء المخطط لها ضمن علامتك التجارية. التحليلات. ردود أفعال العملاء. ستساعدك كل ناحية من النواحي السابقة في إدارة تجربة العملاء، كما ستساعدك معرفة كيفية استخدام كل ناحية منها في بناء منظومة إدارة ممتازة لتجربة العملاء. كيف تبني تجربة استثنائية للعميل عدّ 76% من المديرين التنفيذيين في عالم الأعمال والقادة أن تجربة العملاء تأتي في مقدمة أولوياتهم عندما سئلوا من قبل، بينما تعتقد 80% من الشركات أنهم يقدمون تجارب على قدر عالٍ إلى عملائهم، ولم يجب على السؤال أكثر من 8% منهم. هذه الأرقام ليست مشجعة على أية حال. فعلى أصحاب العلامات التجارية أن يأخذوا هذا الأمر في الحسبان عند بناء استراتيجية لإدارة تجربة العملاء. إليك مجموعة من الحقائق الحيوية التي ينبغي إدراكها خلال العملية: وفقًا لمايكروسوفت فإنّ 96% من العملاء يعدون خدمة العملاء أمرًا أساسيًا في اختيارهم للعلامة التجارية التي سينضوون تحتها. وفقًا لموقع Accenture فقد خسرت الشركات الأمريكية بسبب تبديل العملاء للشركات كنتيجة لسوء خدمة العملاء ما مجموعه 1.6 تريليون دولار. وفقًا لموقع American Express ستزيد مشتريات العملاء من العلامات التجارية التي اكتسبت سمعة ممتازة في خدمة العملاء بمقدار 17%. وفقًا لمايكروسوفت سيفضل 77% من العملاء العلامات التجارية التي تأخذ وقتًا ليس فقط في الاطلاع على ردود فعل العملاء، بل على تطبيق ما جاء فيها أيضًا. سيتمكن فريقك عند وضع تلك الحقائق نصب أعينهم في البدء بوضع الخطوط العريضة لاستراتيجية إدارة تجربة العملاء. وتذكر أن عليك تغطية أربعة نواحٍ على الأقل خلال عملية التخطيط. تعرف على جمهورك لن تتمكن من إنشاء تجربة عملاء تلبي حاجات عملائك إن لم يأخذ فريقك وقته في تحديد الجمهور الذي تستهدفه. إذًا فالخطوة الأولى لفريقك هي تحديد الفئة المستهدفة من الجمهور. إبدأ بطرح الأسئلة التالية على نفسك: ماهي المشاكل التي تقدم منتجاتك أو خدماتك حلولًا لها؟ من هي الفئات التي ستستفيد من هذه المنتجات أو الخدمات؟ بم يهتم أيضًا هؤلاء الأشخاص؟ ماهو أسلوب الحياة الذي يتبعونه؟ ستبدأ في التخطيط لمسيرة عملائك مع علامتك التجارية، بمجرد أن تحصل على أجوبة لتلك الأسئلة. التخطيط لمسيرة عملائك إلى جانبك من الأمور الأساسية في استراتيجية إدارة تجربة العملاء هي مسيرة العملاء مع علامتك التجارية. فهي مقياس لمدى التزامك بحاجاتهم في كل مرحلة من مراحل مسيرتهم إلى جانبك. سيسمح لك التخطيط لمسيرة عملائك بتصور كل خطوة سينفذها العملاء خلال تنقلهم ضمن حلقة المبيعات التي تديرها. سيساعدك التخطيط لمسيرة عملائك في أتمتة عمليات بناء استراتيجية إدارة تجربة العملاء وخاصة إن اخترت التسويق عبر البريد الإلكتروني كأسلوب رئيسي في التواصل. تحليل الأفكار ستكون قادرًا على إرسال المحتوى الذي تريده إلى عملائك عندما تنتهي من تخطيط مسيرتهم مع علامتك التجارية. فقد تتواصل معهم عبر البريد الإلكتروني أو عبر وسائل التواصل الاجتماعي أو من خلال موقعك على الإنترنت. عليك أن تحلل بعناية الأفكار أو المنشورات التي توصلها بغض النظر عن القناة التي تختارها لهذا الغرض. سيعطيك ذلك دلائل حاسمة على ما ينفع وعلى ما لا ينفع. عندما تأخذ وقتًا كافيًا في تحليل أفكارك وتأملها، ستكون قادرًا على الانتقال إلى الخطوة التالية من عملية إدارة تجربة العملاء. السعي خلف آراء العملاء حتى تكتمل عملية إدارة تجربة العملاء، لا بدّ أن تتبين ردود أفعالهم حول ما تقدمه. سيعود العملاء للشراء مرة أخرى من العلامة التجارية التي يفضلونها وسيستمرون في مناصرتها إن شعروا بأن آراءهم مصدر ترحيب وأصواتهم مسموعة. لكن ما أهمية مناصرة العميل؟ يثق 84% من الأشخاص بالمراجعات والتوصيات الشخصية التي يطلعون عليها، ويالتالي كلما ناصرك عملاؤك أكثر على الإنترنت كان ذلك أفضل. إنّ تبين آراء العملاء عملية سهلة وخاصة عند استخدام التسويق عبر البريد الإلكتروني في استراتيجية إدارة تجربة العملاء. تبين لك الصورة التالية مثالًا عن بريد إلكتروني يسأل العميل رأيه: توضح العلامة التجارية في هذه الرسالة أنها لا ترغب فقط باستطلاع آراء عملائهم بل هي محل ترحيب أيضًا. وتذكر أن مدة احتفاظك بعملائك ستزيد إن شعروا بأهمية آرائهم بالنسبة لعلامتك، كما ستزداد مناصرتهم لك وكذلك نسب المبيعات. فالعميل الذي يختبر تجربة إيجابية مع علامة تجارية ويشعر بأهمية رأيه سينفق 140% أكثر من العملاء الذين قيًموا تجريتهم بأنها سلبية. ما هو الدور الذي يلعبه التسويق عبر البريد الإلكتروني في إدارة تجربة العملاء؟ بعد أن عززنا فهمك وفهم فريقك لموضوع إدارة تجربة العملاء، وأوضحنا كيفية العمل على استراتيجيتك في هذا المجال سننتقل إلى دور البريد الإلكتروني في كل ذلك. أشرنا سابقًا إلى سببين أساسيين يدفعانك إلى استخدام التسويق عبر البريد الإلكتروني في إدارة تجربة العملاء. فلن يزيد التسويق عبر البريد الإلكتروني من قيمة مؤشر عائدات الاستثمار (83 دولار لكل دولار يُنفق) وحسب، بل يفضله العملاء كوسيلة للتواصل معهم. كيف تستخدم التسويق عبر البريد الإلكتروني في إدارة تجربة العملاء؟ طالما أنّ التسويق عبر البريد الإلكتروني أداة حيوية، فكيف سنسخرها في استراتيجية إدارة تجربة العملاء؟ ستجد إضافة إلى استطلاع ردود الأفعال والاستبيانات طرق عدة في استخدام التسويق عبر البريد الإلكتروني في إدارة تجربة العملاء منها: رسائل الترحيب. رسائل التأكيد. رسائل الشكر. رسائل التذكير بالمكافآت. رسائل بالحوافز والحسومات. ومغزى الحديث هو أن تتأكد من تطبيق أفضل الوسائل في إدارة تجربة عملائك. استخدم معلومات شخصية في رسائلك: الخصوصية أمر فائق الأهمية في إدارة تجربة العملاء، لذلك تأكد من تجزئة قوائمك البريدية واستخدم محتوى ديناميكيًا. اسمح لعملائك بإعداد الخيارات التي يفضلونها: وذلك للتأكد من وصول أصوات عملائك بطرق شتى. سيساعدك ذلك على استطلاع آرائهم وامتلاك مركز لتجميع الخيارات التي يفضلونها فتعرف عندها ما يريدونه بالضبط وما لا يريدونه وتمنحهم وسيلة للتحكم بتجربتهم. تحضر للانطلاق ينبغي على العلامات التجارية التفكير في مشاركة التسويق عبر البريد الإلكتروني مع إدارة تجربة العملاء، فمنافع هذا الأسلوب تتحدث عن نفسها: يجعل للعميل صوتًا مسموعًا. يزيد فترة المحافظة على العملاء. يزيد مناصرة العملاء. يزيد من نسب المبيعات وأكثر. تذكر أن الغاية من استراتيجية إدارة تجربة العملاء هي تلبية حاجات العملاء وليس حاجاتك. لذلك ركز على عملائك لتحسين أدائك. ترجمة -وبتصرف- للمقال The Role of Email Marketing in Customer Experience Management. اقرأ أيضًا 3 استراتيجيات للتسويق عبر البريد الإلكتروني يجب على كل مسوق أخذها بالحسبان خطوات أساسية لزيادة عدد التقييمات ومراجعات المنتجات باستخدام التسويق بالبريد الإلكتروني التسويق بالبريد الإلكتروني الفعّال لكل مرحلة من مراحل التعامل مع العميل 10 طرق للحدّ من تخلّي العملاء عن القائمة البريديّة من خلال حملات البريد الإلكتروني
-
نعرف جميعًا ما تعنيه العلامة التجارية، وقد يصدف أنك تسوق بالفعل لعلامات تجارية ضمن أعمالك، لكن هل فكرت في بناء علامة تجارية شخصية؟ عليك فعل ذلك لأنه أمر مهم أكثر مما تتصور. ينمو مجتمع المستقلين بسرعة، وأصبح بإمكان أي شخص يستخدم الإنترنت أن يبني قاعدة من المتابعين عندما يعرض خبراته بالطريقة المناسبة. تمثل العلامة التجارية الشخصية كل شيء فهي سمعتك وكيف ينظر إليك الناس وكم يثمنون معرفتك. وباختصار: سيتيح بناءك لعلامة تجارية شخصية مميزة فرصًا احترافية، وهي الطريقة الوحيدة التي تميزك عن منافسيك على المدى الطويل. بتأسيسك لعلامة تجارية شخصية ستكون قادرًا على بناء مجتمع لمتابعيك. كيف ستبني مجتمعا مزدهرا لمتابعيك من خلال التسويق عبر البريد الإلكتروني؟ قد يتبادر إلى ذهنك السؤال التالي أولًا: لماذا سأختار التسويق عبر البريد الإلكتروني بدلًا من وسائل التواصل الاجتماعي؟ يؤمن البعض بعدم جدوى البريد الإلكتروني بالتحديد، لكنها رؤية خاطئة ببساطة. فلن يمنحك البريد الإلكتروني قيمة عالية لعائد الاستثمار ROI وحسب فامتلاك جميع الأشخاص الراشدين لحسابات بريد إلكتروني سيعني انتشارًا أوسع من أي وسيلة للتواصل الاجتماعي. هل تعلم أنّ معدل فتح البريد الإلكتروني يصل إلى 22%؟ وتصل النسبة إلى 10% على إنستغرام، أي أن 10% فقط من متابعيك سيرون منشوراتك. ويسوء الأمر على فيس بوك لتصل النسبة إلى 6% فقط. ووفقًا لموقع Statista، يتحقق حوالي 82% من بريدهم الإلكتروني مرة في اليوم على الأقل، وتقرأ 50% من هذه الرسائل باستخدام الهواتف المحمولة. باختصار: البريد الإلكتروني من أفضل الطرق للوصول إلى جمهورك. كيف تستغل التسويق عبر البريد الإلكتروني لبناء علامة تجارية شخصية؟ نستطيع ذلك عبر اتباع ما يلي: 1. اجعله شخصيا إنّ تجزئة قوائم البريد الإلكتروني هي المفتاح إلى التسويق الناجح، حيث تساعدك هذه العملية في إرسال المحتوى المناسب لكل مشترك. فلقد اشترك هؤلاء في قوائم بريدك الإلكتروني لأنهم أحبوا ما تقوله وما تقدمه وسيساندون شركتك في تحقيق أهدافها. بالطبع لن يناسب محتوى ما كل المشتركين، لذلك ينبغي تقسيمها ضمن مجموعات اعتمادًا على معايير محددة مثل الجنس والموقع الجغرافي وغيرها لكي توجه بريدك الإلكتروني وتخصصه وفقًا لهذه المعايير. سيساعدك ذلك على بناء علاقات شخصية مع عملائك ويشعرون بمكانتهم. بمجرد أن تنفذ تجزئة القوائم، فكر في استقطاب هذه القوائم بالشكل الذي يظهر شخصيتك. فصحيح أنك صاحب أعمال، لكن كيف ستكيف نفسك مع أعمالك؟ فلو كنت تبني شركة تديرها النساء مثلًا، فكّر بشرح القيم التي تمثلها هذه الشركة لشريحة النساء. ولم نقل هذا لنمنعك من تكرار الأمر ذاته مع بقية الشرائح، لكن التفكير بجمهورك سيزيد فرصك في تقديم محتوى موجّه بعناية إلى الأشخاص المناسبين. ويمكنك أيضًا -على سبيل المثال- تقديم رابط إلى مقالة تتحدث عن انطلاقتك في عالم الأعمال وكيف يمكن للنساء الأخريات أن يحذين حذوك. 2. عزز وعي العملاء بعلامتك التجارية تمنحك رسائل البريد الإلكتروني إمكانية تقديم نفسك إلى جمهورك وزيادة معرفتهم بعلامتك التجارية. فباستطاعتك أن تحضّر كل أسبوع أو كل شهر رسالة إخبارية تتضمن معلومات تتعلق بك وبعلامتك التجارية وتوصلها إلى جمهورك، وبالتالي ستُبقي متابعيك على اطلاع بكل جديد يتعلق بعلامتك التجارية. يلعب المحتوى دورًا مهمًا في كل ذلك عندما يكون ممتعًا ومتناغمًا وموجهًا ليلبي حاجاتهم، وبهذا ستضمن قراءة أكبر لرسائلك. ستعزز علامتك التجارية في كل مرة ترسل فيها بريدًا إلكترونيًا، لكنها فرصة أيضًا لتطور نفسك. فبدلًا من أن ترسل بريدك باسم الشركة، فكر أن ترسله باسم محدد (مثل أحمد من شركة حاسوب). أرسل لهم طرفة قد حصلت معك شخصيًا أو لمحة قد تهمهم عنك فقد يعزز هذا التواصل، فإن شعر العملاء أنهم قريبين منك، سيزيد اهتمامهم بشركتك. 3. حضر حملات دعائية أفضل إنّ حصولك على أفكار قيمة عن مشتركيك هو أحد الفوائد الجوهرية من استخدام البريد الإلكتروني. إذ يقدم لك العديد من برامج التسويق عبر البريد الإلكتروني معلومات وأفكار على مختلف الصعد. فستعطيك هذه البرامج فكرة عن تعامل مشتركيك مع الرسائل سواء فتحوها أو نقروا ضمنها أو فتحوا أية ملفات مرفقة معها. يشير معدل فتح الرسائل إلى النسبة المئوية لعدد المشتركين الكلي الذين فتحوا رسائلك الإلكترونية، بينما يشير معدل النقر ضمن الرسالة إلى النسبة المئوية للمشتركين الذين نقروا رابطًا واحدًا على الأقل ضمن رسالتك. يمكنك استخدام هذه البيانات لتنفيذ حملات دعائية أفضل، حيث ستدرك حينها المحتوى الذي ينجح والذي سيفشل. وبالتالي ستوجه نشاطك باتجاه مزيد من تحفيز العملاء على اتخاذ قرار الشراء. إحدى التلميحات المهمة: قد تكون رسائل البريد الإلكتروني مثيرة للإهتمام يعتقد معظم الأشخاص أن رسائل البريد الإلكتروني ليست بإثارة سناب شات أو إنستغرام مثلًا. فعلى الرغم من كل شيء، لن يقدم البريد الإلكتروني مرشحات أو قصصًا، فهو ببساطة طريقة معيارية للتواصل. لكن ذلك لا يعني إطلاقًا أنه ليس جزءًا قيّمًا من استراتيجية تسويقك أو علامتك التجارية. إذ يتحقق أغلب الأشخاص الذين تتراوح أعمارهم بين 10- 40 عامًا من صناديق بريدهم الإلكتروني عدة مرات في اليوم، ذلك أنه جزء من عاداتنا اليومية وبإمكانه أن يغدو مهمًا وممتعًا باستخدام الأدوات الصحيحة. ستجد في الواقع عددًا هائلًا من القوالب والمخططات الجاهزة التي تُستخدم في إنشاء البريد الإلكتروني، وستجد أيضًا صيغًا رائعة لأسطر العناوين التي تزيد من إمكانية فتح الرسالة. صمم عنوانا ملفتا إنّ سطر العنوان شديد الأهمية كما أسلفنا، فهو ما تعتمد عليه لزيادة معدل فتح الرسائل. لهذا السبب خذ وقتك في إنشاء سطر عنوانٍ يثير اهتمام جمهورك، واجعله قصيرًا ويوحي بمضمونه، واجعله موجهًا لفئة من عملائك لتحصد أفضل نتيجة. تجاوز فكرة الترويج وحسب إن استخدمت البريد الإلكتروني لمجرد الترويج لعلامتك وحسب فلن تقدم شيئًا لمشتركيك وسيرون أنّ علامتك التجارية مهتمة بالمبيعات فقط. ركّز على زيادة قيمة المحتوى الذي ترسله بدلًا من توجيهه للبيع فقط. كيف؟ بعرض حلول لمشاكل مشتركيك. خذ بعين الاعتبار تقديم مقالات مفيدة وقدم لهم منصة دعم يسهل الوصول إليها وبادرهم بسلوك يجعل العميل في المقام الأول. لا تبالغ في استخدام الرسوميات استخدم الصور والألوان والخطوط والصور المتحركة التي تناسب مظهر علامتك التجارية، لكن لا تبالغ في ذلك. حيث يستخدم معظم مشتركيك هواتفهم المحمولة للتحقق من بريدهم الإلكتروني، فعليك إذًا أن تجعل الرسائل سريعة التحميل. بالإضافة إلى الرسوميات سريعة التحميل، يمكنك أن تستخدم دائمًا جملًا قصيرة بحجم عريض لتدفع المتابع إلى النقر على زر تنفيذ عملية الشراء. استراتيجيات لشق طريقك في التسويق عبر البريد الإلكتروني تقتضي الخطوة الأولى التي تسبق استخدام البريد الإلكتروني كأداة لترويج علامتك التجارية الحصول على عناوين للبريد الإلكتروني. هنالك طريقتان لذلك، عن طريق عملائك أو عن طريق زوار موقعك اﻹلكتروني. ستكون الخطوة التي تلي تجميع العناوين هو اتخاذ قرار حول طبيعة الرسائل التي سترسلها، فلا بدّ من خطة أولًا. ابدأ بتقديم نفسك عليك أن تظهر كبشري عند إرسالك لبريدك الأول، إذ ينبغي أن تكون جملك طبيعية وأن تبدأ بتقديم نفسك. لا تحاول بيع أي منتج أو خدمة بعد. أظهر لهم قدرًا من الانفتاح وأخبرهم ما الذي تفعله وما الذي سيتوقعونه منك، حدثهم عن أهدافك كي يتعرفوا تمامًا على الشخص الذي يراسلهم عندما تصلهم الرسائل التالية منك. يفضل الناس التواصل مع إنسان بدلًا من عمل. تمثل الصورة التالية رسالة ترحيب من Girls Night IN وتعتبر مثالًا ممتازًا عن الترويج لعلامة تجارية مزودة بمعلومات عن المؤسس وسترى أنّ المتابعين سيعرفون ما الذي ستوصله رسائل هذه المجموعة إليهم: سوق لعلامتك التجارية مثل خبير تاليا ينبغي أن يثقف المحتوى الذي ترسله عبر البريد الإلكتروني جمهورك. وعليك أن تفكر في المجال الذي تعتبر نفسك خبيرًا فيه وما الذي يريده الجمهور الذي تستهدفه. جد مجالًا تختص به وابدأ بإيصال أفكارك. قد لا تقود رسائلك التثقيفية مشتركيك إلى شراء منتجاتك أو خدماتك مباشرة، لكنك ستكسب الثقة من خلال المحتوى القيِّم الذي تقدمه. رفه جمهورك وألهمه ينبغي أن يكون دافعك الرئيسي ترفيه جمهورك وإلهامه من خلال رسائلك الإلكترونية. تواصل مع حس الفكاهة الذي يحملونه، مع قلقهم ومخاوفهم واهتماماتهم. فإن كان المحتوى الذي ترسله قيّمًا وفي التوقيت المناسب، سيبقى جمهورك متلهفًا لكل جديد ترسله. تحضر للانطلاق تذكر أن تستمر حالما تحترف كل التقنيات التي تحدثنا عنها. قد يبدو إنشاء محتوى جديد كل أسبوع كمهمة، لكن بمساعدة بعض الأدوات وبالاستفادة قليلًا من أتمتة المهام، سترفع مستوى رسائلك الإخبارية خلال وقت قصير. ترجمة -وبتصرف- للمقال How to use email marketing for building a personal brand لصاحبه Nilam Oswal. اقرأ أيضًا الدليل الشامل للمبتدئين في التسويق عبر البريد الإلكتروني التسويق بالبريد الإلكتروني وأهم الخطوات اللازمة لتنفيذ حملة تسويقية ناجحة 4 أدوات تسهل عليك مهمة بناء حملتك التسويقية عبر البريد الإلكتروني خمس إستراتيجيات متقدّمة للتسويق عبر البريد الإلكتروني 5 دروس سوف تتعلمها عندما تصبح مسوق من خلال البريد الإلكتروني كيف تقيس نجاح حملات البريد الإلكتروني التسويقية