اذهب إلى المحتوى

ابراهيم الخضور

الأعضاء
  • المساهمات

    164
  • تاريخ الانضمام

  • تاريخ آخر زيارة

كل منشورات العضو ابراهيم الخضور

  1. تستطيع التقاط صورٍ عالية الدقة وتسجيل مقاطع فيديو باستخدام تجهيزة الكاميرا، التي تتصل مع باي 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 تجميع راسبيري باي والتحضير لاستعماله
  2. تُعد سنس هات 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 للعمل تجميع راسبيري باي والتحضير لاستعماله
  3. هل تجذبك فكرة تصميم تجربة المستخدم؟ هل كانت معرفتك بتصاميم تجربة المستخدم عبر قراءة عابرة؟ أم أنك بذلت وقتًا في الاطلاع عليها؟ إن تصميم تجربة المستخدم هي صناعة ديناميكية متداخلة التخصصات تتطور باستمرار. لن تجد أنسب من هذه الفترة لتحترف تصميم تجربة المستخدم، فهو عمل مطلوب عالميًا، مع عدد لا يُحصى من الفرص التي لن تجد عوائق كبيرةً في الحصول عليها، كما يمكنك الوصول إلى موارد هذه الصناعة من خلال الإنترنت، وستجد الكثير من الجهات التي تمنحك شهادات في تصميم تجربة المستخدم، والأهم من ذلك ما يتقاضاه مصمم تجربة المستخدم من مرتبات تفوق المتوسط بكثير. هل استرعى ما قلناه اهتمامك؟ اغتنم فرصة دمج طاقاتك الإبداعية مع إمكاناتك التحليلية لتطوير عالمنا بأفكار تصميمية جيدة. وإليك مجموعة أسباب تدفعك لتصبح مصمم تجربة مستخدم. لتترك أثرا ستعمل بصفتك مصممًا لتجربة مستخدم، على حل مشاكل حقيقية تواجه الناس في واقعهم، إضافةَ إلى بعض المنغصات الصغيرة التي تظهر يومًا بعد يوم (والتي تسبب الكثير بمجموعها). وكما يوحي الاسم "تصميم تجربة المستخدم"، فأساس هذا المجال هو المستخدم واحتياجاته، سواء أكان ما يريده تطبيقًا، أو موقع ويب، أو خدمات مالية، أو مخطط متجر. قد يعطينا سماع عبارة "تصميم تجربة مستخدم" انطباعًا عن عملاء أو تصميم وبيع منتجات، لكن ما يحدث في الواقع هو أن هذا المستخدم قد يكون مريضًا في مستشفى أو طبيبًا، وقد تكون جدتك أو حتى أنت نفسك في الكثير من المسارات. لقد امتلأ العالم بالتصاميم الجيدة والسيئة، فتخيل إذًا كيف ستتغير حياتنا إلى الأفضل إن سادت التصاميم الجيدة؟ هنا ستظهر قيمة ميزتين مهمتين لتصميم تجربة المستخدم: الشمولية 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. اقرأ أيضًا مهام مصممي تجربة المستخدم مخرجات تصميمية يجب على كل مصمم تجربة مستخدم أن يتقنها دليلك الشامل لفهم المسارات المهنية لمجال تجربة المستخدم
  4. يستخدِم المتصفح خيطًا واحدًا افتراضيًا لتنفيذ شيفرة جافاسكربت في صفحتك، إضافةً إلى تخطيط الصفحة وإعادة ضبط العناصر وتجميع الموارد المستهلكة، ويعني هذا أنّ التنفيذ الطويل لدوال جافاسكربت قد يعيق خيط التنفيذ، والذي يقود بدوره إلى صفحة ضعيفة الاستجابة، وبالتالي تجربة مستخدِم سيئة، كما تستطيع استخدام أداتَي تحليل الأداء 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 المتحركة على أداء مواقع الويب خطوات أساسيّة لتحسين أداء المواقع
  5. قد ترغب في نشر صفحة الويب البسيطة التي بنيتها ليزورها الجميع وذلك برفعها إلى خادم ويب، لهذا سنناقش في هذا المقال طريقة تنفيذ الأمر مستخدِمين عدة خيارات وأدوات متاحة، مثل عميل 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. اقرأ أيضًا مساعدة المبتدئين في فهم كيفية رفع الموقع على الإنترنت مدخل إلى أسماء النطاقات في شبكة الإنترنت الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث المدخل الشامل لتعلم تطوير الويب
  6. لا تستهن بالتفكير التصميمي 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. اقرأ أيضًا المرحلة الأولى من عملية التفكير التصميمي: التعاطف مع المستخدمين المرحلة الثالثة في عملية التفكير التصميمي: مرحلة التفكير المرحلة الرابعة في عملية التفكير التصميمي: مرحلة بناء النماذج الأولية استخدام التفكير التصميمي لتخطي مشاكل رائد الأعمال
  7. يصف المقال طريقة إعداد خادم اختبار محلي على حاسوبك وكيفية استخدامه، كما ننصحك بدايةً بالاطلاع على كيفية عمل الإنترنت والتعرُّف على خادم الويب. الملفات على الخادم المحلي موازنة بالملفات على خادم بعيد يمكنك بكل بساطة فتح ملف 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. اقرأ أيضًا دليل إعداد خادم ويب محلي خطوة بخطوة الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث
  8. يختلف أثر رسوم 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
  9. إن كنت نشرت موقعك الإلكتروني وأصبح متاحًا للجميع، فهل أنت على ثقة بأن كل شيء يجري على ما يرام؟ سنناقش في هذا المقال عدة خطوات قد تتبعها لتتأكد من عمل موقعك، وبعض الإجراءات التي يمكن اتخاذها لتلافي بعض المشاكل التي تظهر. يملك خادم الويب البعيد سلوكًا قد يختلف أحيانًا عن سلوك الخادم المحلي الذي اختبرت عليه موقعك، لهذا من الأفضل اختبار الموقع عند نشره على الويب مباشرةً، وقد تفاجئك كمية المشاكل التي قد تظهر مثل الصور الغير معروضة أو الصفحات الغير محمَّلة أو التي تعاني بطأً في التحميل وغيرها، لكنك ستجد لحسن الحظ أنّ معظم هذه المشاكل ليست بتلك الخطورة، وإنما هي أخطاء بسيطة أو بعض الإشكالات في إعدادات الخادم الذي يستضيف الموقع. سنطّلع إذًا في مقالنا على الطريقة التي نُشخِّص بها المشاكل التي تعترض موقع الويب إبان نشره وآلية معالجتها، وإليك بعض الاختبارات البسيطة التي لابد من إجرائها فور نشر موقعك على الويب. اختبر الموقع على متصفحك لا بدّ من تشغيل موقعك الإلكتروني من خلال متصفحك فور نشره على الويب كي تتفحص عمله وتتأكد من سير كل شيء كما هو متوقع له. صورة مفقودة لنلق نظرةً على هذه الصفحة الاختبارية من موزيلّا، حيث ستلاحظ عدم وجود صورة يونيكورن 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. اقرأ أيضًا كيف تنشر صفحة أو موقع ويب قمت بتصميمه على الإنترنت الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث كيفية التعامل مع الويب المدخل الشامل لتعلم تطوير الويب
  10. تتكون الأداة 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 تحسين الظهور في محركات البحث
  11. توفر الواجهة البرمجية لعامل الخدمة 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
  12. يصف هذا المقال أداةً غايةً في الأهمية لتحليل أداء صفحات ويب فيما يتعلق بتنفيذ شيفرات 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 للمبتدئين: كيف تصمم أول صفحة ويب لك
  13. يعد التسويق عبر البريد الإلكتروني من أكثر أقنية التسويق فعالية وربحًا وفقًا لقيمة عائد الاستثمار 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 اقرأ أيضًا أهم الأفكار التي يجب أن تعرفها عن التسويق عبر البريد الإلكتروني القائمة البريدية: الوصفة السريّة لنجاح الشركات الناشئة كيف تحصل على قائمة بريد الكتروني مُتفاعلة لماذا يجب عليك أن تتجنب شراء القوائم البريدية الجاهزة كيف تربح المال من قائمتك البريدية؟
  14. يعي المسوقون من جميع المستويات أنّ تجربة العملاء لن تؤثر على نسب المبيعات الأولية فقط بل تلعب دورًا مهمًا في المحافظة على العملاء. حيث تساهم أقنية تسوق مختلفة في نجاح إدارتك لتجربة العميل (اختصارًا 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 طرق للحدّ من تخلّي العملاء عن القائمة البريديّة من خلال حملات البريد الإلكتروني
  15. نعرف جميعًا ما تعنيه العلامة التجارية، وقد يصدف أنك تسوق بالفعل لعلامات تجارية ضمن أعمالك، لكن هل فكرت في بناء علامة تجارية شخصية؟ عليك فعل ذلك لأنه أمر مهم أكثر مما تتصور. ينمو مجتمع المستقلين بسرعة، وأصبح بإمكان أي شخص يستخدم الإنترنت أن يبني قاعدة من المتابعين عندما يعرض خبراته بالطريقة المناسبة. تمثل العلامة التجارية الشخصية كل شيء فهي سمعتك وكيف ينظر إليك الناس وكم يثمنون معرفتك. وباختصار: سيتيح بناءك لعلامة تجارية شخصية مميزة فرصًا احترافية، وهي الطريقة الوحيدة التي تميزك عن منافسيك على المدى الطويل. بتأسيسك لعلامة تجارية شخصية ستكون قادرًا على بناء مجتمع لمتابعيك. كيف ستبني مجتمعا مزدهرا لمتابعيك من خلال التسويق عبر البريد الإلكتروني؟ قد يتبادر إلى ذهنك السؤال التالي أولًا: لماذا سأختار التسويق عبر البريد الإلكتروني بدلًا من وسائل التواصل الاجتماعي؟ يؤمن البعض بعدم جدوى البريد الإلكتروني بالتحديد، لكنها رؤية خاطئة ببساطة. فلن يمنحك البريد الإلكتروني قيمة عالية لعائد الاستثمار 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 دروس سوف تتعلمها عندما تصبح مسوق من خلال البريد الإلكتروني كيف تقيس نجاح حملات البريد الإلكتروني التسويقية
  16. ماهو علم نفس الألوان؟ وما هي مشكلة علم نفس اللون في التسويق وفي الترويج للعلامات التجارية، وكيف تتخذ قرارات قابلة للتطبيق تتعلق باستخدام الألوان في التسويق والترويج؟ وكيف تجد لوحة الألوان التي تناسبك. إنّ استخدام علم نفس الألوان في الإقناع، هو أحد أكثر جوانب التسويق متعة وإثارة للجدل. إنّ المشكلة كانت دومًا في عمق التحليل. فعلى الرغم من أنّ نظرية الألوان موضوع معقد ومربك، لكن من السهل إيضاح علم نفس الألوان باستخدام الإنفوجرافيك الذي لا يغطي أفكارًا أكثر مما يعرضه. لن تجعلنا مثل هذه النقاشات ذات المستوى السطحي محضَّرين لاتخاذ قرارات ذكية حول استخدام الطيف اللوني في إيصال الرسالة الصحيحة لعلامتنا التجارية. لكن لماذا تتسم مثل هذه المحادثات اللونية بالسطحية الواضحة؟ ماهو علم نفس الألوان؟ يُعرَّف علم نفس الألوان بأنه دراسة لتحديد أثر اللون في التصوّرات والسلوكيات. يركز علم نفس الألوان في مجال التسويق والترويج للعلامات التجارية على تأثير الألوان في انطباعات العملاء عن علامة تجارية، وقدرتها على إقناعهم في التفكير بعلامة تجارية محددة أو شراء منتج ما. فهذا مجال ينبغي التفكير في استغلاله عند تحضير أدوات التسويق أو بناء عمل جديد أو إعادة الترويج لعمل قائم. تأمل التالي: وجد باحثون في دراسة حملت العنوان "Impact of color on marketing"، أنّ 90% من الأحكام السريعة على المنتجات قد اتُخذت بناء على اللون فقط! مشكلة علم نفس اللون في التسويق وفي الترويج لعلامات تجارية جرت محاولات لا تعد ولا تحصى لتصنيف طريقة تفاعل الأشخاص مع الألوان. يعتمد الإحساس بالألوان حقيقة على التجارب الشخصية، فمن الصعب وضع مقياس عالمي لكيفية إدراكها والشعور بها. لقد أظهرت دراسات أنّ ما يفضله الأشخاص بالإضافة إلى خبراتهم ونشأتهم والفوارق الثقافية والمجتمعية والسياق الذي قد يؤثر في اختيارهم لونًا سيشوب الانطباع الذي يولده اللون في الفرد. فدقة الفكرة التي مفادها أن اللون الأصفر أو البنفسجي قد يحرض نوعًا من المشاعر الخاصة، هي كدقة المعلومات التي تحصل عليها عند قراءة راحة يدك عند عرّافة. لن تكون دقيقًا عندما تتخذ قرارات فضفاضة كقولك "الأخضر يعني الهدوء"، إذ سيختلف الوضع باختلاف سياق الحديث. فقد يستخدم اللون الأخضر مع علامة تجارية لأغراض بيئية مثل Seventh Generation أو قد يُستخدم للترويج لفضاءات مالية مثل Mint. فبينما يعطي اللون البني مظهر الخشونة - انظر كيف تستخدمه Saddleback Leather- قد يعطي في سياق آخر شعورًا دافئًا وودودًا (كالعيد) أو لتحريك شهيتك (ككل إعلانات الشوكولا التي تراها). ويبقى لدينا الكثير لنتعلمه ونفكر به إن أدركنا ببساطة أنه لا أجوبة مضمونة على الأسئلة الجوهرية، ومفتاحنا هو البحث عن طرق تطبيقية لاتخاذ قراراتنا حول الألوان. كيف تتخذ قرارات قابلة للتطبيق تتعلق باستخدام الألوان في التسويق والترويج؟ خلاصة الكلام أنه لا توجد إرشادات واضحة وحاسمة لاختيار ألوان علامتك التجارية. فقد تتمكن من الاطلاع ببساطة على مخطط إنفوجرافيك وتقرر ما تريده، لكن في الواقع لن تجد جوابًا محددًا للسؤال "ماهو اللون الصحيح لعلامتك التجارية؟". إنها الحقيقة، وسيبقى للسياق الذي تعمل ضمنه الاعتبار الأول. فما يهم هو المشاعر والحالة النفسية والصورة التي يولدها المنتج أو العلامة التجارية. أما الخبر الجيد، فهو أنّ علم نفس الألوان سيساعدك على الاختيار المناسب. اللون الصحيح ملائم لعلامتك التجارية وجد باحثون في دراسة جرت عام 2006 أنّ العلاقة بين العلامات التجارية والألوان تتمحور حول الملاءمة المحسوسة للون الذي تستخدمه علامة تجارية محددة. وبكلمات أخرى: هل يناسب اللون المختار ما يُباع من منتجات؟ كما وجد الباحثون -فيما يتعلق بانتقاء اللون الصحيح- أن توقع ردود فعل العملاء على ملائمة اللون أهم بكثير من اللون بحد ذاته. وبالتالي عند انتقائك لألوان علامتك التجارية أو ما تسوق له، إسأل نفسك (أو بالأحرى استطلع آراء عملائك): "هل هذا اللون سيلائم ما أبيعه". سيظهر اللون الصحيح خصوصية علامتك التجارية تُأثر الألوان بشدة على ميل العملاء إلى الشراء نظرًا لتأثيرها على كيفية تصوّرهم للعلامة التجارية. حيث تؤثر الألوان بطريقة رؤية العميل لشخصية العلامة التجارية التي يقيّمها. وبينما تتماشى ألوان مع سمات محددة (كالبني مع الخشونة مثلًا)، تؤكد معظم الدراسات الأكاديمية حول الألوان والترويج للعلامات التجارية أن الأهم بلا منازع هو أن تدعم الألوان المنتقاة الشخصية والخصوصية التي تريد إظهارها بدلًا من تماشيها مع الرؤية النمطية لانتقاء اللون. قادت عالمة النفس والأستاذة في جامعة ستانفورد جينيفر إيكر دراسات على هذا الموضع بالتحديد، وأشارت دراستها التي تحمل العنوان "Dimensions of Brand Personality" إلى وجود خمسة أبعاد جوهرية تلعب دورًا في إبراز شخصية الشركة. وأن العلامات التجارية قد تبدي سمتين من سمات الخصوصية، لكنها في الغالب تحت هيمنة واحدةٍ من هذه السمات فقط. لذا اسأل نفسك: ما السمة الشخصية التي أريدها لعلامتي التجارية، وكيف سأستخدم اللون لإيصال هذه الشخصية؟ اللون المناسب يجذب عملاءك يعد عمل جو هالوك الذي يحمل العنوان "Colour Assignment" عن العلاقة بين علم نفس اللون والجنس من أكثر الدراسات أهمية في هذا المجال. حيث تظهر بيانات هالوك تفضيلًا واضحًا لألوان محددة وفقًا لجنس العميل. لكن من المهم أن تدرك أن معظم الذين أجابوا كانوا من المجتمعات الغربية. فبيئة الشخص -وخاصة إدراكه الثقافي- سيلعب دورًا قويًا في فرض ما يجده أحد الجنسين لونًا ملائمًا، وسيؤثر ذلك بدوره على التفضيلات الشخصية للألوان. وتظهر دراسات أخرى عن إدراك الألوان وتفضيل الألوان أن الرجال يفضلون عمومًا الألوان القاسية بينما تفضل النساء الألوان الأكثر نعومة، وذلك عندما يتعلق الأمر بتدرجات اللون وسطوعها وشدتها. وأشارت الدراسة أيضًا إلى ميل الرجال لاختيار الألوان التي تميل للقتامة (ألوان مع مسحة سوداء) بينما تميل النساء إلى الألوان الفاتحة (ألوان مع مسحة بيضاء). وعلى الرغم من الجدل المحتدم حول هذه النقطة، يمكن للعلامات التجارية أن تعمل خارج نطاق التصور النمطي للألوان التي يفضلها الجنسين. وفي الواقع ستجد العديد ممن تلقى جوائزًا لخروجه عن المألوف. لا ينبغي التشدد في مفهوم الملائمة المحسوسة وافتراض أن العلامة التجارية ستخفق خارج هذه الإطار، وذلك أنه لا اتفاق على اختيار الألوان بين من شاركوا في الاستبيانات، وهذا ما يقودنا مباشرة إلى النقطة التالية. اللون الصحيح سيميّز علامتك التجارية كشف دراسات أخرى أن أدمغتنا تفضل العلامات التجارية التي تميزها مباشرة، مما يجعل اللون عنصرًا مهمًا في تكوين هوية العلامة التجارية. وأشارت إحدى المقالات الصحفية إلى أهمية اختيار لون العلامة التجارية الجديدة لضمان تميزها عن المنافسين المعروفين. سيساعدك اختيار اللون الصحيح على إبراز علامتك التجارية. فكّر بالمبدأ النفسي المعروف بتأثير الإنعزال the Isolation Effect والذي ينص على أن أي عنصر "يبرز كإبهام متورم" سيرسخ على الأرجح في الذاكرة. حيث أشارت الدراسات بوضوح إلى أن المشتركين في الاختبارات كانوا قادرين على تمييز وتذكر العنصر بطريقة أفضل بكثير سواء كان نصًا أم صورة إن كان بارزًا بشكل ملفت عن محيطه. وخلصت دراستين عن التوليفات اللونية أحدهما تقيس الاستجابة الجمالية والأخرى عما يفضله العملاء، إلى أن العملاء يفضلون أيضًا اللوحات اللونية التي تعرض تباينًا شديدًا لألوان التمييز Accent colors، على الرغم من تفضيل الأغلبية العظمى للوحات اللونية ذات التباين المتشابه. ويعني هذا وفقًا لمصطلحات تنسيق الألوان إنشاء بنية بصرية تتكون من ألوان أساسية متماثلة ثم تغيير سطوعها باستخدام ألوان تمييز مكملة (وفقًا لأسلوب الألوان الثلاث). يلعب هذا المفهوم دورًا كبيرًا في عالم التسويق أيضًا، ويمكن أن نفكر فيه على أنه صفحة ويب بخلفية من لون أساسي تتداخل معها ألوان تمييز تحملها لبقية العناصر -كما يظهر في تصميم جوش بيرز الذي سنعرضه في الصورة التالية- مما يشكل بنية هرمية ضمن موقعك لتدرب العملاء على الألوان التي تشجع على تنفيذ إجراء ما. لم كل هذا الاهتمام؟ إن الفهم الصحيح لهذه المبادئ سيجنبك الوقوع في فخ تحسين نسبة المبيعات بناء على المبدأ اللوني الذي يضلل الكثيرين. تأمل الموقع التالي لإحدى العلامات التجارية الذي يشير إلى زيادة في نسبة المبيعات بعد تغيير اللون. عزز تغيير لون الزر إلى الأحمر المبيعات بنسبة 21%، لكن لا يمكننا بالتأكيد إتخاذ أية فرضيات حول "قوة تأثير اللون الأحمر" بمعزل عن بقية المؤثرات. من الواضح أن بقية عناصر الصفحة تميل إلى اللون الأخضر، ويعني هذا ببساطة أن زر اتخاذ القرار الشراء ذو اللون الأخضر سيتمازج مع بقية العناصر المحيطة، بينما يُبرز اللون الأحمر تباينًا شديدًا فهو مكمل للون الأخضر. فكر أخيرًا -وهذا أمر حساس جدًا- بتعريفك لنجاح اختبارات كهذه. فالمزيد من الإشتراكات والنقرات لا تشكل سوى مقاييس معزولة ومضللة غالبًا للمسوقين الذين يحاولون استخدامها ببساطة لمجرد أنها سهلة القياس. يمتلك اللون الصحيح اسما صحيحا على الرغم من التصور المختلف للألوان المختلفة، إلا أن الاسم الذي يصف اللون مؤثر أيضًا. فوفقًا لدراسة تحمل العنوان A rose by any other name …، طلب من المشتركين أن يقيّموا المنتجات بناء على أسماء ألوانها -مثل مساحيق التجميل- فكانت المنتجات المفضلة هي التي يحمل لونها اسمًا أنيقًا. فوُجد مثلًا أن اللون الذي يسمى "موكا mocha" كان محببًا أكثر من "البني" على الرغم من أن الاسمين يعرضان اللون نفسه. وقد أثبتت دراسة أخرى أن التأثير نفسه ينطبق على أنواع مختلفة من المنتجات، فقد رأى العملاء أن الأسماء المتقنة لألوان الطلاء ستجعلها تبدو للعين أكثر جمالًا من تلك التي سُميّت ببساطة. كما أظهرت الدراسة أن الأسماء الفريدة وغير الإعتيادية للألوان هي الأكثر تفضيلًا وبالنسبة لكل المنتجات ابتداءً بحبوب الهلام إلى الملابس. فقد تُختار أقلام التلوين التي تحمل اسم "رازماتاز" مثلًا أكثر مما ستُختار إن سُمّي لونها "أصفر ليموني" جد لوحة الألوان التي تناسبك ها قد وصلنا إلى ختام هذا المقال ولم نجد بعد طريقة مثالية لاختيار اللون أو مخطط الألوان المناسب. وربما نكون قد طرحنا أسئلة أكثر مما أجبنا. إن ازدحام مقالة بعبارات "ربما" و"نوعًا ما" لا يعني بأية حال التوقف عن التفكير الناقد لمحتواها. لذلك استخدم أساليب البحث المتاحة لتتحدى الأفكار المسبقة وتسأل أسئلة أفضل. فهذا هو أسلوب المثابرة للوصول إلى أجوبة أفضل. ترجمة -وبتصرف- للمقال Color Psychology in Marketing and Branding is All About Context لصاحبه Gregory Ciotti. اقرأ أيضًا الألوان في تصميم الرسوميات ونظرية الألوان كل ما يجب عليك معرفته عن نظرية الألوان لغير المصممين أدوات عديدة لانتقاء الألوان تفيدك في عملية التصميم كيف تنشئ ألوانك الخاصة في برنامج سكريبوس Scribus
  17. إن كنت تشعر أنك تقضي وقتًا عصيبًا في الاطلاع على الكم الهائل من المعلومات التي تحيط بك حول التسويق بالعمولة affiliate marketing، أو أنّ عملك كمسوق لا يتطور على الرغم من إضافة روابط التسويق بالعمولة إلى منشوراتك، سنرشدك عبر خطواتٍ عشر إلى احتراف التسويق المتقدم بالعمولة وتكوين استراتيجية مناسبة لعملك. مدخل موجز إلى التسويق المتقدم بالعمولة على الرغم من كون التسويق بالعمولة (تقديم منتجات من علامات تجارية أخرى إلى متابعيك مقابل عمولة) من أفضل الوسائل لكسب المال عبر الإنترنت وتأسيس قناة انسيابية لزيادة الدخل، لكن عليك أن تتذكر دائمًا أنّ التسويق المتقدم بالعمولة سيتعلق دائمًا بإيجاد حلول للمشاكل. فهذا النوع من التسويق لن يتعلق بك، بل هو موجه لقرّائك ومتابعيك. يضع البعض التسويق بالعمولة في إطار الكسب السريع للمال، ويعدونه طريقة للاسترخاء وانتظار الأموال حتى تتدفق إلى محفظتك. فأن توصي بالمنتجات التي تعجبك أمر رائع يدر عليك بالمال الذي سينساب بالتأكيد إلى محفظتك بمجرد أن يأتي العمل ثماره، لكن العمل الصعب الذي لا يمكنك تفاديه، هو بناء قاعدة من المتابعين الذين يثقون بك بما يكفي، وكذلك إبداع محتوى معين يأتي بنتائج جيدة باستمرار. لسوء الحظ، لن يكون وضع الروابط عشوائيًا ضمن مقالاتك أو منشوراتك ثم انتظار تدفق المال الأسلوب الأفضل في استراتيجية التسويق المتقدم بالعمولة، لكنه يبقى مع ذلك، الأسلوب الأكثر استخدامًا من قبل مالكي صفحات الويب والمؤثرين في هذا المجال. إن كنت تتطلع لتأسيس دخل يمكنك الاعتماد عليه مستخدمًا التسويق المتقدم بالعمولة، فلا بدّ أن تضيِّق شبكتك لاستهداف الأشخاص الذين يرغبون في الشراء لكن يلزمهم القليل من الثقة بالمصدر والذي ستلعب أنت دوره. عشرة نصائح لتسويق متقدم وناجح بالعمولة إليك مجموعة من النصائح التي ستحسن استراتيجيتك في التسويق بالعمولة، سواء أكنت بدأت العمل للتو أو أنك مستعد للتقدم في هذا المجال. 1. استعمل الكلمات المفتاحية الصحيحة تأكد دائمًا من كتابة محتوى يجذب الأشخاص المهتمين فعلًا بشراء المنتج. عليك من وجهة نظر مثالية، اختيار كلمات مفتاحية سهلة التصنيف مكتوبة بحجم صغير تشير إلى الشراء. 2. اختر منتجاتك بعناية وفكر بما تسوق له ينبغي عليك في الواقع تسويق المنتجات التي تمتلك بعض الخبرة فيها وهذا ما يبني الثقة مع القارئ. لكن المنتجات التي عليك تسويقها من وجهة نظر عالم الأعمال، هي تلك التي تحمل لك العمولة الأعلى. إن كنت بصدد كتابة محتوى أو تنفيذ حملة دعائية كاملة لمنتج تحصل منه على عمولة، لا بدّ أن تحصل منها على ما يستحق الوقت الذي ستقضيه في إنجازها. فالمنتجات المكلفة التي لن تضطر إلى بيع كميات كبيرة منها هي المفتاح. ستجد هذه المنتجات بسؤال نفسك أولًا عما قد ترغب بشرائه من المنتجات التي تختص بتسويقها، أو بتصور ما قد يحتاجه القراء. أجرِ بعض الأبحاث على الإنترنت عندما تضع قائمة بتلك المنتجات ووازن بينها لتجد الخيارات الأنسب لك ولقرائك. 3. تعرف إلى مديرك في التسويق نادرًا ما يستفيد المسوقون من إمكانيات مدير عملية التسويق بالعمولة على الرغم من أنهم موجودون لمساعدتك في تنفيذ المبيعات بالنيابة عن شركاتهم. فقد يقودك التواصل معهم لتطوير شراكات بما يلائم تخصصك إلى نتائج عظيمة بما في ذلك الحسومات التي قد يحصل عليها القرّاء، والصور الدعائية التي تلبي احتياجاتك وغيرها من الخيارات المربحة. 4. اطلع على أنواع مختلفة من المحتويات المتعلقة بالتسويق بالعمولة ينبغي أن تُركّز مقالات التسويق التي تكتبها على كلمات مفتاحية صحيحة وعلى المقدمة وصلب الموضوع بدلًا من كونها مجرد مكانٍ لتضع فيه روابط التسويق. لديك العديد من الأساليب التي قد تساعدك في كتابة مقالات للتسويق بالعمولة، وأكثرها شعبية أسلوب تجميع المنتجات كأن يكون عنوان المقال "أفضل عشرة آلات تصوير تناسب ميزانيتك". قد يتضمن المحتوى المتعلق بالتسويق بالعمولة أفكارًا أخرى مثل: موازنة عمولة بأخرى: كأن يكون العنوان ("أ" أو "ب" أي من الخيارين هو الأنسب للشركاء الجدد؟) أو ("أ" أو "ب" أي الخيارين الأفضل مذاقًا؟). ستجد طرقًا عدة لتختار العنوان، لكن عليك التأكد من أنه سيستهدف مجموعة محددة من الأشخاص (متابعيك بالطبع). كتابة مراجعة نقدية لمنتج: كأن تستخدم المفتاح "كيف تفعل كذا.." مثل "كيف تتناول طعامًا صحيًا عندما تكون مشغولًا (لشركة مثل هيلو فريش Hello Fresh)"، أو أن تبدأ مباشرة في كتابة المراجعة النقدية. 5. استخدم محتوى متفرعا في مقالاتك فبدل أن تبعثر روابط التسويق بالعمولة هنا وهناك في مقالتك بانتظار تحقيق ما تصبو إليه، عزز وادعم مقالات التسويق بمحتوى يتعلق فعليًا بما تختصه المقالة. ولن تحسّن فرص التقييم العالي لمقالتك بهذه الطريقة وحسب، بل ستجذب أشخاصًا ينصب اهتمامهم بالاطلاع عمومًا على المحتوى ليصبحو مهتمين ومتابعين لمقالاتك التسويقية. فإن كانت مقالتك عن بطاقة رحلة على القطار، أنشئ أدلة سياحية للبلد أو البلدان التي يمكن استخدام البطاقة ضمنها واربطها مع مقالتك الأصلية. 6. استخدم محفزات ملفتة لإغراء المشترين إن أردت جعل مقالاتك التسويقية لا تقاوم وبالتالي تحقيق المبيعات بسرعة فلا تنسى أن معظمنا يحب الصفقات المربحة والهدايا المجانية، وغالبًا ما يزيد ذلك من مردود العملية. فإن زوّدت مقالتك برموز حسم Discount code حصلت عليها من مدير التسويق أو بمكافآت إضافية Extra bonuses حققتها بنفسك (يمكن مشاركتها عبر جوجل درايف أو أية روابط قابلة للمشاركة)، فسيعنى ذلك أن العملاء قد يفضلون استخدام روابطك التسويقية بدلًا من روابط غيرك. يمكنك استخدام هذه الطريقة أيضًا لإضافة صيغة استعجال إلى أحداث ستجري خلال فترة زمنية مؤقتة، وستحسن فرص ظهور مقالاتك عند البحث عن كلمات مفتاحية مثل مكافآت Bonus أو رموز حسم Discount code أو هدايا مجانية Free gifts. تتنوع المكافآت الإضافية التي يمكنك استخدامها بطرق شتى، لكن مع ذلك لابدّ أن تتعلق مباشرة بمحتوى المقال. من الأمثلة البسيطة التي قد نذكرها: كتاب إلكتروني (مثل دليل سياحي يتعلق بعملية التسويق التي ننفذها) أو مفكرة أو وصول مجاني إلى مجموعة فيس بوك أو دورة تعليمية قصيرة أو حسومات. إن كنت تسوق لمجموعة أو حزمة من المنتجات (كتب إلكترونية أو دورات تعليمية عادة) فقد تضيف دفاتر أو جداول إلكترونية تساعد الأشخاص في تتبع المحتوى وتقودهم خلال تصفحه. 7. أنشئ صفحات ارتباط للمشاركة السريعة إن المكوّن الرئيسي لتسويق متقدم بالعمولة هم المتابعين الشغوفين كالزوار الذين يعودون باستمرار أو مشتركي البريد الإلكتروني. سيساعدك وجود صفحات هبوط أو ارتباط في تحويل المتابعين غير المهتمين إلى متابعين شغوفين، ويظهر الأمر الجيد في ذلك تحديدًا عند تسويق منتجات ليست من اختصاصك تمامًا. فإن سألك أحدهم النصيحة بشأن شبكة تواصل اجتماعي ستتمكن من تحويلهم إلى صفحات الارتباط المخصصة لهذا الأمر. يمكنك ضمن هذه الصفحات الحديث عن المنتج الذي تحبه ولماذا كما يمكنك تضمين عروض متنوعة، وتسهل على الزوار اتخاذ قرار الشراء. ومن الرائع جدًا استخدامها مع روابط الجر swipe-up على إنستغرام أو كردود على أسئلة في فيس بوك. ويمكنك بالتأكيد ربطها بمحتوى مناسب ضمن موقعك. 8. استخدم طريقة البيع الخاطفة Flash sale سجّل ضمن قوائم الرسائل الإخبارية وضمن صفحات فيس بوك لتعرف متى ستصدر الشركات منتجات جديدة أو متى ستدفع بعضها إلى السوق. يمكنك حينها استخدام حسابات التواصل الاجتماعي الخاصة بك وقوائم البريد الإلكتروني لتنبيه متابعيك إلى الأمر. تتيح لك متابعة المبيعات كتابة مراجعات نقدية باكرًا لمنتج طرح أو دُفع به إلى السوق وهذا ما يعطيها وقتًا ليرتفع تقييمها أو أن تلفت الانتباه على بينتريست Pinterest. تأكد من امتلاكك لصفحات ارتباط جاهزة لكي تنشرها بسهولة على وسائل التواصل الاجتماعي. خطط لهذا الأمر مسبقًا لتجعل الأمر سلسًا ومجدٍ من ناحية الوقت قدر الإمكان بأن تُجهّز مجلدات التواصل الاجتماعي والرسوميات والعناوين وتضع جداول زمنية لإرسال البريد الإلكتروني. استثنِ من قوائم بريدك الإلكتروني أي شخص غير مهتم بآخر تحديثات هذا المنتج لكي لا يشعر أيًا من عملائك أنه يتلقى بريدًا غير مرغوب به Spammed. سيكون تقديم المكافآت هنا أمرًا ممتازًا، فالمنافسة على أشدها خلال هذه الفترات. 9. فكر باستخدام العروض المفاجئة إن أردت توسيع دخلك أو أعمالك تدفع العروض المفاجئة العميل نحو اختيار عرض لمرة واحدة. من المحتمل أنك صادفت أمرًا مماثلًا عندما تصفحت مدونات أشخاص آخرين أو ربما بعد أن نزّلت هدية مجانية مثل دورة تدريبية بحسم يصل إلى 50% إن اشتركت خلال الساعة القادمة. استخدم إبداعك في استخدام هذه العروض. وعلى الرغم من تجنب الكثيرين استخدامها، لكن فعاليتها تضاهي بلا شك المبيع الخاطف. فإن اشترى أحدهم مثلًا الغرض الذي تسوقه خلال الفترة الزمنية لسريان العرض المفاجئ، فقد يمنحك هؤلاء غرضًا آخر مجانًا ككتاب إلكتروني أو دورة تعليمية أو عرض تقديمي على الإنترنت، وهذا مجرد مثال عن فائدة هذه العروض. 10. استغلال البريد الإلكتروني في التسويق بالعمولة يمكن أن يكون التسويق باستخدام البريد الإلكتروني جزءًا من استراتيجية التسويق المتقدم بالعمولة التي تتبعها طالما أن جمهورك لن يشعر بأنها رسائل إلكترونية غير معروفة المصدر(غير مرغوبة). إذ ينبغي أن يكون الجمهور قادرًا على الإنسحاب بسهولة من حملتك التسويقية الآلية عندما تبدأ وإلا قد تخسر مشتركيك. فليس أسوأ من أن تُقصف فقط برسائل مبيعات مصدرها مؤلف محتوى إلكتروني أحببت عمله لأشهر. مع ذلك، وطالما أن ما تسوقه بالعمولة جدير باهتمام متابعيك، سيكون التسويق بالاستفادة من البريد الإلكتروني أداة عظيمة ضمن صندوق أدواتك وخاصة مع اقتراب مناسبات خاصة وعند الإعلان عن تخفيضات، كما يمكنك أتمتة الكثير من المهام التي تتطلبها العملية. تعد هذه المنصات سهلة الاستخدام وقابلة للنمو ولها ميزات متعددة تبسط أمور الإشارة إلى جمهورك ووضعهم في مجموعات وإعداد سلاسل الرسائل الإلكترونية الموجهة إليهم. تأكد من أخذ الوقت الكافي لزيادة حجم قوائم البريد الإلكتروني بإضافة أشخاص جدد إليها باستخدام مغانط لجذب العملاء magnet lead ( كتقديم أدلة مجانية أو نصائح لتوفير المال والوقت أو عروض تقديمية مجانية على الإنترنت) والحرص على التواصل معهم بوتيرة منتظمة وأسلوب صادق يظهر خبرتك ويبني الثقة بينكم. إليك فكرة عن سلاسل بريد إلكتروني بسيطة يمكنك الاستفادة منها: رسائل الترحيب: وتتألف من رسالتين إلى ثلاث يمكنك من خلالها استعراض خبرتك وكسب الثقة وإيصال مغناطيس لجذبهم وكذلك إثارة حماستهم لتلقي البريد التالي ودفعهم لاتخاذ خطوات ملموسة وتوضيح ما هو المتوقع من بريدك الإلكتروني. رسائل لفت الانتباه: وتتألف من رسالتين إلى ثلاث تتحدث عن قيم وتلميحات وقصص وأفكار ملهمة وإشارات إلى المنتجات لكن لا تتجاوز الحدود (تذكر أن إخلاء مسؤوليتك أمر مطلوب). حافظ على عوامل الإعجاب والثقة بما تقدمه وابق المواضيع المطروحة متعلقة بالمنتجات المعنية. رسائل متابعة التطورات: يمكنك البدء خلالها في تقديم منتجاتك والشركات التي تسوق لها بشكل أكبر. ترجمة -وبتصرف- للمقالة 10 Steps to Mastering Advanced Affiliate Marketing لصاحبته Jessica Esa. اقرأ أيضًا كيف أبدأ بالتسويق بالعمولة كعامل مستقل كيف تُنوّع نشاطك كمستقل عبر التسويق بالعمولة كيف تصنع المال عبر التسويق بالعمولة عمل تسويق بالعمولة وتتبعه والمشاكل التي قد تصادفك
  18. إنّ التسويق الرقمي عمل مزدهر، ومن أهم ما على المسوقين فعله هذه الأيام هو إضافة التسويق عبر الهاتف المحمول إلى حملاتهم التسويقية. يجعل تعاملنا جميعًا مع الهواتف المحمولة -ولو نظريًا- من هذه الأجهزة وسيلة واسعة الانتشار كما هو حال البريد الإلكتروني. وتركز استراتيجيات التسويق للأعمال الصغيرة من خلالها على استخدام آليات بسيطة ترفع من نسب المبيعات. إذ يمكن أن تصل الأعمال الصغيرة إلى عملاء أكثر إذا ما استفدنا من هذه الاستراتيجيات كجزء من حلول التسويق متعدد الأقنية، وذلك بتوفير عروض مخصصة لهؤلاء العملاء. كيف تعزز استراتيجيات التسويق عبر الهاتف المحمول نسب المبيعات يمكن أن يزيد التسويق عبر الهواتف الذكية من اهتمام الناس بالعلامة التجارية التي تسوق لها، وأن يحسّن نسب مبيعاتك نظرًا لوجود أكثر من خمسة مليارات مستخدم لهذه الأجهزة. وتشير الأرقام إلى المستوى الذي وصل إليه استخدام أجهزة الهاتف المحمولة حيث: ثمانية وستون في المئة من حملات التسويق عبر البريد الإلكتروني يتابعها المهتمون عبر أجهزة الهاتف المحمولة. بيع في الولايات المتحدة حسابات للشراء عبر إعلانات الهاتف المحمول ما نسبته 72% من إجمالي الإعلانات الرقمية. ينفق المسوقون أكثر من نصف ميزانياتهم على إعلانات الهاتف المحمول. ترتفع المبيعات عندما يُستخدم التسويق عبر الهاتف المحمول كجزء من مقاربة التسويق متعدد الأقنية. يشجع استخدام الهواتف الذكية أكثر من 70% من الأشخاص على الشراء من المتاجر بعد استخدام أجهزتهم في الحصول على معلومات أكثر حول المنتج أو الخدمة المقدمة. شهد أكثر من 80% من الأعمال نموًا في العائدات عام 2018 عندما استخدمت استراتيجية التسويق الموجه المتقدمة. أنجزت أكثر من 40% من المعاملات المالية على الإنترنت عبر أجهزة الهاتف المحمولة. تساعد استراتيجيات التسويق للأعمال الصغيرة عبر الهاتف المحمول الناس على إيجاد معلومات عن منتجاتك والتي ستحوّلهم بالتأكيد إلى عملاء لك. عشرة استراتيجيات تسويق عبر الهاتف المحمول تقود بالفعل الأعمال الصغيرة إن أردت تحويل حركة المبيعات إلى موقعك، عليك أن تضع خطة عصرية تستغل استراتيجيات التسويق للأعمال الصغيرة عبر الهاتف المحمول. 1. التسويق المعتمد على الموقع الجغرافي إن توفر لديك تطبيق للهاتف المحمول يدعم أعمالك الصغيرة، ستكون قادرًا على استخدام تقنيات التسويق المعتمدة على الموقع الجغرافي مثل geofencing لتسوق منتجاتك إلى مستخدمي الهاتف المحمول في منطقة محددة. وتظهر فائدة الأمر خصوصًا للأعمال الصغيرة التي تمتلك متاجر شعبية أو أكشاك على الأرصفة، وستكون عملية عند استخدامها مع مواقع التجارة الإلكترونية التي تقدم خدمات محلية مثل توصيل الوجبات أو خدمات السفر. ويعد أكثر من 80% من المسوقين أنّ التسويق المعتمد على الموقع الجغرافي سيقود إلى زيادة في قيمة ثلاثة مؤشرات أساسية هي: زيادة بنسبة 85% في قاعدة العملاء، و83% في معدلات التجاوب، و83% في انخراط العملاء في عمليات الشراء. 2. تصميم مواقع متجاوبة مع الأجهزة المتصفحة لها ستحتاج إلى مواقع ويب وإعلانات الهاتف المحمول ومحتوى تسويقي مهيأ للعمل على الهواتف المحمولة وليس قابلًا للعرض عليه فحسب. فقد تضاعف مواقع الويب المصممة للعمل على الهواتف المحمولة ثلاثة مرات فرصة زيادة نسبة المبيعات على الهواتف المحمولة بنسبة 5% أو أكثر، ومع ذلك لا تتعدى الشركات التي تستخدم هذا الأسلوب نسبة 35%. هنالك عدة أساليب أخرى -بالإضافة إلى التصميم المتجاوب- قد تساعدك في إعداد موقعك ليتعامل مع صنف محدد من الأجهزة. ومن أفضل الطرق لإنجاز ذلك هي المنصات المخصصة لتطوير مواقع الويب المخصصة للهواتف المحمولة واستخدام اللغة HTML5 في تصميم الموقع واعتماد التصميمات المتكيفة Adaptive design. 3. الإعلانات على مواقع التواصل الاجتماعي على الرغم من هيمنة التسويق عبر البريد الإلكتروني، ستجد أن التسويق عبر مواقع التواصل الاجتماعي تشق طريقها بنجاح في عالم الأعمال الصغيرة وينبغي التركيز على ذلك. إن اضطررت إلى إنشاء حسابات كثيرة على منصات التواصل الاجتماعي الأكثر شعبية، لست مضطرًا لاستخدامها جميعًا لتطوير أعمالك. أجر اختبار موازنة A/B testings لتقف على أداء منشوراتك عبر المنصات المختلفة. تشجع مواقع التواصل الاجتماعي الأشخاص على شراء الأشياء من العلامات التجارية التي يفضلونها. وتشير الإحصائيات إلى أن 76% من المستهلكين الأمريكيين قد اشتروا شيئًا ما لمجرد مشاركة العلامة التجارية منشورًا يصف ميزات المنتج. فمعرفة الناس لوجود هذه العلامة التجارية، هو الهدف الرئيسي لمعظم الشركات بما يخص استراتيجية استخدام مواقع التواصل الاجتماعي. 4. المحتوى الملائم للهاتف المحمول تستهدف تهيئة التصميم للعمل على الهاتف المحمول عناصر في البنية الخارجية لموقعك عادةً، وهذا أمر مختلف عن كون الموقع ملائمًا للعرض على الهاتف المحمول. فتقديم المحتوى على الهواتف المحمولة مختلف عن حواسب سطح المكتب. ستحتاج إلى جمل أقصر وإلى إدراج عناوين رئيسية ووسائط مناسبة كالصور والفيديوهات ذات الدقة العالية. كما يرغب متابعيك على الأغلب بالتصفح السريع وأخذ لمحة مختصرة، لذا سهّل هذا الأمر عليهم. قد يساعدك استخدام العناوين عند إنشائك لمقاطع الفيديو في دفع الناس إلى المتابعة، إذ يشغّل معظم المتابعين (85% منهم) مقاطع الفيديو على فيس بوك دون صوت. ستساعدك العناوين على توصيل فكرتك لهم حتى لو كتموا صوت الفيديو. 5. تعزيز البحث الصوتي يتوجه الناس إلى البحث الصوتي مع تطور إمكانياته التي أوصلتها الأجهزة الذكية إلى منازلهم. ستزوّد أكثر من نصف التجهيزات المنزلية بمعدات تفعّل صوتيًا بحلول العام الحالي وزيادة بمقدار 42% فوق العدد الحالي لمالكيها. وستجد أنّ 34% من الأشخاص الذين لا يمتلكون هذه التقنية مهتمون باقتنائها. يمتلك البحث الصوتي الإمكانية لتحريك المبيعات، فأكثر ما يفعله الناس بعد تنفيذ بحث صوتي هو التواصل مع ممثلي الأعمال التي يعثرون عليها أو تصفح موقع الشركة الإلكتروني أو زيارة متجر محلي. وتحفز جميع هذه الأفعال المبيعات. 6. التسويق عبر الرسائل النصية تبدأ حملات التسويق عبر الرسائل النصية بمنح الأشخاص فرصة الاشتراك في الرسائل مستقبلًا، فلا يمانع 75% من الأشخاص من استقبال رسائل نصية قصيرة من الشركات التي يحبونها ويقرؤها 90% من مستقبليها خلال ثلاث دقائق من وصول الرسالة. ويدل هذا على معدلات الفتح الخيالية للرسائل التي يقرؤها الناس بالكامل تقريبًا. ستلاحظ فعالية بطاقات الحسم الرقمية عندما تستخدم الرسائل النصية ضمن استراتيجيات التسويق عبر الهاتف المحمول. إذ يزيد استخدام الناس للبطاقات التي تصل إليهم عبر الرسائل النصية عشرة مرات عن تلك التي تصلهم من مصادر أخرى. 7. الفيديوهات والرسوميات المتحركة GIFs ولّت الأيام التي يقرأ فيها الناس كلمات الرسائل النصية التي ترد إلى صناديق بريدهم، إذ يفضلون المحتوى المسلي وسهل المتابعة، مما يجعل الفيديوهات والرسوميات المتحركة المرشحين الرئيسيين لتحسين استراتيجيتك في التسويق عبر الهاتف المحمول. يفضل قرابة 75% من الناس متابعة الفيديوهات عندما يتعلق الأمر بالاطلاع على منتج جديد بغض النظر عن مدته. يشجع استخدام الفيديوهات في حملات التسويق عبر مواقع التواصل الاجتماعي العملاء على المتابعة، فأكثر من نصف العملاء سيتابعون أخبار علامة تجارية بعد متابعة فيديو على مواقع التواصل الاجتماعي، وسيرتفع هذا الرقم عندما ينتمي العميل إلى جيل هذه الألفية. 8. دعم المستخدم عبر مواقع الويب وضمن التطبيقات من أفضل الوسائل التي ترفع معدلات المحافظة على العملاء، هي التجربة الجيدة التي تقدمها لهم. وتعد آليات الدعم التي يسهل الوصول إليها والتعامل معها طريقة ملائمة لتعزيز تجربة العميل. وسواء أكانت وسيلة الدعم المقدمة هي ميزة المحادثة المباشرة على الموقع أو ميزة الاتصال المباشر مع أحد المعنيين ضمن التطبيق، سيؤثر وجودها بشدة على تجربة العميل. يتوقع قرابة 40% من زوار موقعك وجود ميزة المحادثة المباشرة، وسترتفع هذه النسبة إلى 50% إن استخدم العملاء الهواتف النقالة في الوصول إلى موقعك. إذ يعد نصف عدد الزوار أن المحادثة المباشرة هي الوسيلة المفضلة للتواصل. 9. الحملات الدعائية الموجهة يعد توجيه التسوق نحو فئة من العملاء من أكثر الاستراتيجيات فعالية في التسويق للأعمال الصغيرة. فمن الممكن إطلاق حملات دعائية تعتمد على موقع العملاء أو على الطريقة التي يتفاعلون بها مع موقعك بمجرد أن تجمع بعض المعلومات عن زوار موقعك وعملائك. يقول 52% من الأشخاص أنهم سيتسوقون في مكان آخر إن تلقوا بريدًا إلكترونيًا تسويقيًا لا يخاطبهم تحديدًا. إذ يتوقع العملاء أن يكون البريد كالتالي مثلًا: يتعدى توجيه البريد الإلكتروني والمخاطبة الشخصية مجال التسويق عبر البريد الإلكتروني، حيث يرغب 51% من الأشخاص أن تلبي الشركات مايحتاجونه وأن تصلهم إعلانات تعتمد على تجاربهم الشرائية السابقة، كما يزداد احتمال شراء 80% من الأشخاص من الشركات التي تقدم عروضًا شخصية. 10. نماذج الاشتراك عندما يسمح لك العملاء في التواصل معهم فقد امتلكت المفتاح المثالي لتطبيق التسويق الرقمي. وستجد أنك بحاجة إلى استخدام نماذج الاشتراك opt-in forms سواء أكنت تحاول بناء قائمة بريد إلكتروني أو أردت التوسع في التسويق عبر الرسائل النصية. قد يكون نموذج الاشتراك بسيطًا كنافذة منبثقة popup على موقعك وقد يكون أكثر تعقيدًا بأن تعرض على العميل بداية تحميل كتاب إلكتروني يتطلب بريده الإلكتروني. نصائح لاستعمال استراتيجيات التسويق للأعمال الصغيرة عبر الهاتف المحمول عليك أن تضع خطة عصرية تستغل عدة استراتيجيات في التسويق للأعمال الصغيرة عبر الهاتف المحمول إن أردت أن تجني ثمار تعبك في التسويق. قد لا يحتاج موقعك للتجارة الإلكتروني إلى كل هذه الاستراتيجيات، لكن استخدام المناسبة منها ستحسن بالتأكيد نسب مبيعاتك. من الممكن أن تقودك مقاربة التسويق المعتمدة على أقنية متعددة إلى نجاح أكبر موازنة بالتزامك إحدى هذه القنوات. لهذا استخدم الإرشادات التالية في دمج استراتيجيات التسويق عبر الهاتف المحمول ضمن خطتك للتسويق متعدد الأقنية: تجزئة القوائم: فقد تقود القوائم المجزأة بناءً على معايير محددة إلى صفحة الهبوط وبالتالي المنتجات الصحيحة. أتمتة البريد الإلكتروني: إذ ستصل الحملات الدعائية الآلية (المؤتمتة) إلى مشتركيك في التوقيت الصحيح. تعزيز الحملات الدعائية: حيث تستخدم الحملات المعدة لأغراض محددة وسائل التواصل الاجتماعي والتسويق عبر البريد الإلكتروني والإعلانات الرقمية للوصول إلى العملاء المحتملين. وباختيارك للأدوات الصحيحة، ستتمكن من إعداد حملة رقمية تعمل بطريقة صحيحة لإرسال البريد الإلكتروني في التوقيت الصحيح ونشر المحتوى المناسب عبر منصات التواصل الاجتماعي المستهدفة. تحضر للانطلاق تختلف فعالية الاستراتيجيات المتبعة في التسويق للأعمال الصغيرة عبر الهاتف المحمول من صناعة لأخرى، لكن هذه التقنيات واسعة الانتشار في عالم التسويق. تذكر هذه النصائح عندما تعد حملتك الدعائية القادمة: يختلف التسويق عبر الهاتف المحمول عن التسويق عبر أجهزة سطح المكتب: لذلك حضر محتوى يأخذ هذا الأمر بالحسبان ويساعد على انخراط أكبر للعملاء. يحب الناس أن يروا خصوصية في التسويق: يقود البريد الإلكتروني وبطاقات الحسم الموجهة شخصيًا إلى مبيعات أعلى. الحملة الدعائية الآلية هي الأسرع والأكثر فعالية: تسهل أدوات التسويق الوصول إلى عملائك بوتيرة أعلى. ستحقق النجاح في حملتك الدعائية القادمة إن ركزت على توظيف بعض الاستراتيجيات التي طرحناها في التسويق للأعمال الصغيرة عبر الهاتف المحمول. ترجمة -وبتصرف- للمقالة 10 mobile marketing strategies for small businesses that actually drive traffic اقرأ أيضًا هل آن الأوان للتخلي عن المكالمات الباردة في عالم التسويق؟ كيف يصبح الاتصال البارد (cold calling) أفضل من AdWords خطوات نجاح المزيج التسويقي الرقمي ما هو التسويق التحادثي وكيف تستثمره في إنجاح أعمالك؟
  19. يمكن برمجة عمل مكوّنات فيزيائية إضافةً إلى تطوير البرمجيات التي تُنفّذ على الشاشة، مثل المكوّنات الإلكترونية التي تتصل مع باي عبر أرجل المنصة GPIO، أو ما يُعرف باسم الحوسبة الفيزيائية physical computing. يتبادر إلى الأذهان أثناء التفكير بمصطلحي برمجة programming أو كتابة شيفرة Coding، بأنها برمجيات الحاسوب software مباشرةً، لكن الأمر ليس كذلك دومًا؛ فقد نكتب برمجياتٍ تتعامل مباشرةً مع العتاد الصلب hardware، ويُعرف هذا النوع من البرمجة باسم الحوسبة الفيزيائية أو برمجة المكونات الفيزيائية، حيث ترتبط الحوسبة الفيزيائية كما يوحي اسمها بالتحكم بتجهيزات فيزيائية حقيقية؛ فعندما تغيّر برنامجًا في الغسالة الآلية لضبط درجة حرارة حساس الحرارة القابل للبرمجة، أو عندما تضغط زرًا عند إشارة المرور لتعبر الطريق بأمان، فأنت تُنفِّذ حوسبةً فيزيائيةً. يُعد حاسوب راسبيري باي أداة رائعة لتعلم الحوسبة الفيزيائية بفضل منصة أرجل الدخل والخرج ذات الأغراض العامة general-purpose input/output -أو اختصارًا GPIO-. التعرف على منصة الأرجل GPIO ستجد منصة أرجل الدخل والخرج العامة GPIO، المكونة من صفين من الأرجل أو الدبابيس المعدنية عند الحافة العلوية لراسبيري باي، وستمنحك هذه المنصة القدرة على توصيل تجهيزات فيزيائية مثل المؤشرات الضوئية LEDs، أو القواطع switches إلى باي للتحكم بها من خلال برامجٍ تصممها بنفسك. قد يكون اسم المنصة مربكًا، لكنه يصف بالفعل ما تتكون منه، حيث يمكنك استخدام أي رجلٍ لاستقبال إشارةٍ كهربائية وعندها تُدعى رجل دخل input pin أو لإرسال إشارة كهربائية وتدعى عندها رجل خرج output pin. كما تُعرف باسم منصة Header، لأن الأرجل مجمعةٌ ومرتبةٌ وظاهرةٌ على اللوحة الإلكترونية للجهاز، ومن هنا يأتي اسم "منصة الدخل والخرج ذات الأغراض العامة general-purpose input/output header". تتكون المنصة من 40 رجلًا معدنيًا، حيث يمكنك استخدام بعضها في الاتصال مع تجهيزاتٍ خارجية، بينما يزوّدك بعضها بالتغذية الكهربائية، ويُحجز بعضها لأغراض التواصل مع تجهيزات مخصصة لتوسيع راسبيري باي، مثل Sense HAT التي سنشرحها مفصلًا في مقال لاحق. إذًا، هناك فئاتٌ مختلفةٌ للأرجل ولكلٍّ منها وظيفته الخاصة والتي سنلخصها في الجدول التالي: 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; } نوع الرجل التيار الكهربائي مصدر التغذية والوظيفة أرجل 3V3 تعطي تغذية كهربائية جهدها 3.3 فولت مصدر تغذية كهربائية جهده 3.3 فولت وهو نفسه الجهد الذي يعمل عليه راسبيري باي داخليًا أرجل 5v تعطي تغذية كهربائية جهدها 5 فولت مصدر تغذية كهربائية جهده 5 فولت وهو نفسه الجهد الذي يدخل إلى راسبيري باي عبر منفذ USB-C أرجل الأرضية (Ground (Gnd وتمثل أرجل الأرضية التي يُقاس الجهد بالنسبة إليها وتُعد 0 فولت تُستخدم وصلة الأرضية لإكمال الدارة الكهربائية المرتبطة بمصدر التغذية. أرجل دخل وخرج GPIO XX أرجل الدخل والخرج للأغراض العامة وأرقامها من خانتين XX وهي الأرجل التي تتحكم بسلوكها من خلال برامجك وتُعرّف بأرقام من 2 وحتى 27 أرجل توصيل تجهيزات موسِّعة ID EEPROM أرجل محجوزة لاستخدامات خاصة محجوزة للاتصال بالتجهيزات المرتبطة بالأعلى Hardware Attached on Top -أو اختصارًا HAT- وغيرها من التجهيزات الملحقة. تمنحك المنصة GPIO طريقةً ممتعةً وآمنةً في نفس الوقت لتتمرن على الحوسبة الفيزيائية، لكن ينبغي الحذر في التعامل معها؛ لذلك لا تحاول ثني الأرجل عند فصل أو وصل التجهيزات؛ ولا تصل أبدًا رجلين ببعضهما مباشرةً عن طريق الخطأ أو متعمدًا إذا لم يُطلب منك ذلك بوضوحٍ في توجيهات المشروع الذي تبنيه، حيث تُعرف هذه الحالة بالدارة المقصورة، وقد تؤدي إلى ضررٍ غير قابلٍ للإصلاح في راسبيري تبعًا للأرجل التي قُصرت. العمل مع العناصر الإلكترونية تمثل المنصة GPIO جزءًا فقط مما ستحتاجه لتبدأ مسيرتك في الحوسبة الفيزيائية، بينما تمثل العناصر الإلكترونية، وهي الأجهزة التي ستتحكم بها عبر GPIO، الجزء الآخر. ستجد آلاف العناصر الإلكترونية المتاحة، لكن معظم مشاريع GPIO مكوّنةٌ من العناصر التالية: لوحة اختبار مثقبة breadboard وتعرف أيضًا باللوحة التي لا تحتاج إلى لحام solderless، حيث تسهل هذه الأداة تأمين الاتصال بين العناصر الإلكترونية لمشروعك بسهولة؛ فبدلًا من وصل العناصر عن طريق الأسلاك، تؤمن لك لوحة الاختبار ثقوبًا تدفع فيها أرجل العناصر لتتصل ببعضها عبر مساراتٍ معدنيةٍ مخفيةٍ تحت السطح البلاستيكي للّوحة. ستجد في كثيرٍ من لوحات الاختبار أقسامًا منفصلةً لتوزيع التغذية الكهربائية، وهذا سينعكس على سهولة بناء الدارات. لن تحتاج إلى لوحة الاختبار للبدء بالحوسبة الفيزيائية طبعًا، لكنها أداةٌ مفيدةٌ جدًا. وصلات طرفية jumpers تُستخدم لوصل العناصر الإلكترونية إلى باي أو مع بعضها بعضًا إذا لم تستخدم لوحة الاختبار. يتوفر ثلاثة أنواع من الوصلات الطرفية، هي: وصلة مذكرة- مؤنثة "M2F"، والتي ستحتاجها لوصل لوحة الاختبار مع أرجل المنصة GPIO. وصلة مؤنثة- مؤنثة "F2F"، والتي تُساعد في ربط العناصر ببعضها إذا لم تستخدم لوحة اختبار. وصلة مذكرة- مذكرة "M2M"، وهي تُستخدم لربط نقطةٍ (مجموعة ثقوب متصلة ببعضها) من لوحة اختبار بنقطةٍ أخرى. ستحتاج بعض هذه الأنواع من الوصلات الطرفية أو جميعها تبعًا لمشروعك؛ فإذا استخدمت لوحة الاختبار مثلًا، فلن تحتاج الوصلة F2F. قاطع آني أو زر كبس push button وهو نوعٌ القواطع أو الأزرار مشابهة للتي نستخدمها في مقبض الألعاب، وتأتي عادةً برجلين أو أربعة ويعمل كلاهما مع باي. يُعد زر الكبس عنصر دخل، حيث يمكن لبرنامجك مراقبة هذا الزر عندما يُكبس ليُنفِّذ مهمةً ما. يتواجد أيضًا نوعٌ آخر من القواطع المعروفة باسم القواطع الدائمة latching، وهي تُبقِي التيار الكهربائي موصولًا عند تحويلها إلى وضع التوصيل على خلاف أزرار الكبس، التي يجب عليك الاستمرار في ضغط أزرار الكبس حتى يستمر التيار الكهربائي بالمرور. المؤشرات الضوئية LEDs أو ثنائي المساري الضوئي Light Emitting Diode وهي أجهزة خرج يمكن التحكم بها من خلال البرامج مباشرةً، حيث يُضيء المؤشر عندما يمر فيه التيار الكهربائي، ومن المؤكد أنك تستخدمها في منزلك سواءً الصغيرة منها، مثل التي تنبهك أن غسالتك في وضع التشغيل، أو الكبيرة التي تُنير بها الغرفة. تأتي هذه الأضواء بأشكالٍ وألوانٍ وأحجامٍ كثيرة، لكنها لا تتناسب جميعها مع راسبيري باي، فلا تستخدم تلك التي صُممت للعمل على جهدٍ 5 أو 12 فولت. المقاومات Resistors وهي عناصر إلكترونية تتحكم بتدفق التيار الكهربائي، وتتوفر بقيمٍ متنوعة تُقاس بواحدة الأوم Ohms ويرمز لهذه الواحدة بالرمز Ω. وكلما زادت قيمة المقاومة مقدرةً بالأوم قلَّ تدفق التيار الكهربائي عبرها. تُعد حماية المؤشرات الضوئية من استجرار تيار كهربائي مرتفع قد يؤدي إلى تضررها أو إحداث ضررٍ بباي من أكثر استخدامات المقاومات شيوعًا في مشاريع الحوسبة الفيزيائية الخاصة براسبيري باي، ولهذا السبب ستحتاج إلى مقاوماتٍ قيمتها بحدود Ω 330. يُقدّم الكثير من مزوّدي العناصر الإلكترونية مجموعاتٍ كاملةً من المقاومات تتضمن عددًا من القيم المختلفة للاستخدامات الشائعة مما يمنحك مرونةً أكثر في اختيار المقاومات المناسبة. جرس تنبيه كهروانضغاطي Piezoelectric buzzer ويدعى عادةً منبه buzzer، أو مصوت sounder؛ وهو جهاز خرج يصدر ضجيجًا صوتيًا كما تُصدر المؤشرات الضوئية أضواءً، ويتألف المنبه من غلافٍ بلاستيكي يضم صفيحتين معدنيتين تهتزان باتجاهين متعاكسين عند مرور التيار في الجهاز، فيصدر الصوت المميز له. للمنبه نوعان، فعال Active أو غير فعّال passive، فاحرص على استخدام المنبه الفعّال لأنه أبسط استخدامًا. مكونات وعناصر إلكترونية شائعة مثل المحركات التي تحتاج إلى لوحة تحكمٍ خاصةٍ لتوصيلها إلى باي، وحسّاسات الأشعة تحت الحمراء IR sensors التي تستشعر الحركة، وحسّاسات الرطوبة والحرارة التي يمكن استخدامها لتوقع حالة الطقس، والمقاومات الضوئية LDRs وهي أجهزة دخلٍ تلتقط الضوء على عكس المؤشرات الضوئية. يزوّدك الباعة في كافة أنحاء العالم بمكوّناتٍ مخصصةٍ للحوسبة الفيزيائية لاستخدامها مع راسبيري باي، ويمكن أن تكون مفردةً أو ضمن علب أدوات تزوّدك بكل ما تحتاجه لتبدأ، انظر حولك من الباعة والموزعين المحليين أو أصحاب المتاجر الإلكترونية أو الدوليين الذين يشحنون الطلبات إلى بلدك. لإكمال المشاريع في هذا الفصل ينبغي تأمين العناصر والمكوّنات التالية: ثلاث مؤشرات ضوئية LEDs، أحمر وأخضر وأصفر أو كهرماني. قاطعين آنيين أو زري كبس. منبّه فعّال Active وصلات طرفية من النوعين مذّكرة- مؤنثة "M2F" ومؤنثة-مؤنثة "F2F". لوحة اختبار ووصلات طرفية من نوع مذّكرة- مذّكرة "M2M" ولك الحرية في استخدام هذين المكونين أو عدمه. قراءة الرموز اللونية للمقاومات وتقدير قيمتها تُصنّع المقاومات لتغطي مجالاتٍ واسعةٍ من القيم، ابتداءً من مقاومةٍ معدومةٍ تماثل قطعةً من سلك، وحتى قيمٍ مرتفعةٍ جدًا يمكن أن يصل حجمها إلى حجم ساقك. لن تجد قيمة المقاومة مطبوعةً عليها سوى في بضعةٍ أنواعٍ من المقاومات، وبدلًا من ذلك يستخدم المصنعون ترميزًا لونيًا خاصًا على شكل خطوطٍ أو أشرطةٍ تلتف حول جسم المقاومة. لقراءة قيمة المقاومة: احمل المقاومة بحيث تكون مجموعة الخطوط المتقاربة إلى اليسار والخط المفرد إلى اليمين. انظر إلى لون الخط الأول وخذ القراءة من العمود الأول المُسمى خط أول/ ثانيفي الجدول، ثم انظر إلى الخط الثاني وخذ قيمته من نفس العمود فستحصل على الرقمين الأول والثاني من قيمة المقاومة؛ فلو كان الخطان برتقاليان، فسيكون الرقمان الأول 3 والثاني 3 ويشكلان العدد 33؛ وإذا احتوت المجموعة اليسارية ثلاث خطوط، كرّر الأمر بالنسبة للخط الثالث وستحصل على الرقم الثالث من قيمة المقاومة؛ وفي حال احتوت أربعة خطوط، فعليك الرجوع إلى الإنترنت لقراءة الترميز. 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; } اللون خط أول/ثاني مضاعفات (خط ثالث) السماحية (الخط المفرد) أسود 0 ‎×100‎ - بني 1 ‎×101‎ ±1% أحمر 2 ‎×102‎ ±2% برتقالي 3 ‎×103‎ - أصفر 4 ‎×104‎ - أخضر 5 ‎×105‎ ±0.5% أزرق 6 ‎×106‎ ±0.25% بنفسجي 7 ‎×107‎ ±0.1% رمادي 8 ‎×108‎ ±0.05% أبيض 9 ‎×109‎ - ذهبي - ‎×10-1‎ ±5% فضي - ‎×10-2‎ ±10% بلا لون - - ±20% يمثّل الخط الثالث أو الرابع في المجموعة اليسارية القيمة الواجب جدائها بالعدد الذي شكلته الخطوط السابقة للحصول على القيمة الاسمية للمقاومة. انتبه إلى أن ‎100=1 و 101‎=10 و 102‎=100 و 103‎=1000 وهكذا؛ فلو كان الخطان الأول والثاني برتقاليان والثالث برتقالي، فهذا يعني أن قيمة المقاومة هي العدد 33 مضروبًا بالعدد 1000 وستكون النتيجة 3000 أوم. يمثّل الخط المفرد السماحية tolerance؛ وهي مقياسٌ لاقتراب القيمة الاسمية للمقاومة من القيمة الفعلية التي تعطيها، حيث تعني المقاومات الرخيصة التي تأتي بخط سماحيةٍ فضي مثلًا أن القيمة الفعلية للمقاومة ستزيد أو تقل عن القيمة الإسمية بمقدار 10%، أي أن مقاومةً قيمتها الاسمية 1000 أوم قد تكون فعليًا في المجال 900- 1100 أوم؛ بينما تأتي المقاومات المرتفعة السعر مثلًا بخط سماحية رمادي، أي باختلافٍ لا يتعدى 0.05 % أعلى أو أدنى من القيمة الاسمية. لن تؤثر السماحيات كثيرًا في مشاريع الهواة، حيث ستعمل أية مقاومة كما هو مطلوب بغض النظر عن سماحيتها. يبقى علينا الإشارة إلى موضوع المضاعفات، فعندما تتجاوز قيمة المقاومة 1000 أوم ستُقدّر بواحدة الكيلو أوم "kΩ"؛ أي إذا كانت قيمة المقاومة 2200 أوم، فستكتب على الشكل 2.2 كيلو أوم؛ أما عندما تتجاوز قيمته 1000 كيلو أوم أو 1000000 أوم، فستُقدَّر عندها بالميغا أوم  "MΩ"، أي إذا كانت قيمة المقاومة 22000000، فستكتب 2.2 ميغا أوم. مشروعك الأول: مرحبا أيها الضوء يمثّل تشغيل مؤشرٍ ضوئي الخطوة التقليدية الأولى في الحوسبة الفيزيائية، تمامًا كما تمثّل طباعة عبارة "!Hello world" على الشاشة الخطوة الأولى لتعلم البرمجة. سنحتاج في مشروعنا هذا إلى: مؤشر ضوئي LED. مقاومة قيمتها 330 أوم أو أية مقاومة قريبةٍ منها وصلات طرفية مؤنثة-مؤنثة. ابدأ بالتحقق من صلاحية المؤشر الضوئي الذي ستستخدمه من خلال قلب لوحة باي حتى تصبح المنصة GPIO عموديةً وفي الجهة اليمنى من اللوحة. صِل أحد طرفي المقاومة 330 أوم إلى أي رجل 3.3 فولت (يُشار إليها في لوحة باي بالرمز 3V3) مستخدمًا سلكًا مزودًا بوصلةٍ طرفية مؤنثة-مؤنثة، ثم صل الطرف الآخر للمقاومة بالرجل الأطول (الرجل الموجبة) للمؤشر الضوئي والتي تُعرف بالمصعد أو الأنود Anode. صِل بعد ذلك الرجل الأقصر (الرجل السالبة) للمؤشر الضوئي والتي تُعرف بالمهبط أو الكاثود cathode إلى أي رجٍل أرضيةٍ GND في المنصة GPIO، كما هو موضحٌ في الشكل التالي. شكل 1-6 صل المؤشر الضوئي إلى أرجل باي ولاتنس المقاومة! سيضيء المؤشر طالما باي يعمل، وإذا لم يحدث ذلك، تأكّد من توصيلات الدارة من خلال التحقق من قيمة المقاومة، حيث من المفترض ألّا تكون عالية جدًا، وتحقق من التوصيل الجيد للأسلاك والوصلات الطرفية، ثم تأكد من استخدامك للأرجل الصحيحة للمنصة GPIO والأرجل الصحيحة للمؤشر الضوئي الذي لن يعمل إلا إذا وصلت رجله الأطول إلى جهدٍ موجب والأخرى إلى جهدٍ سالب، حيث تُعد الرجل الأرضية بمثابة جهدٍ سالب. بمجرد أن يضيء المؤشر فهو جاهزٌ للبرمجة، لذلك افصل الوصلة الطرفية من الرجل "3V3" وصلها بالرجل رقم 25 للمنصة GPIO، والتي يُشار إليها على لوح باي بالرمز GP25، وسينطفئ عندها المؤشر الضوئي. شكل 2-6 افصل السلك عن الرجل 3V3 وصله بالرجل GP25 أصبحت الدارة جاهزةً، وتستطيع الآن كتابة برنامج بلغة سكراتش أو بايثون لتشغيل وإطفاء المؤشر الضوئي. التحكم بالمؤشر الضوئي باستخدام برنامج سكراتش 2 افتح برنامج سكراتش 2 من قائمة راسبيري باي، ثم انقر على زر "كتل أخرى More Blocks" ضمن لوح الكتل البرمجية، واختر بعدها "إضافة موسِّع Add an Extension"، واختر الموسِّع "Pi GPIO" ثم انقر الزر OK. سيُحمّل الأمر الكتل البرمجية اللازمة للتحكم بأرجل المنصة GPIO باستخدام سكراتش، حيث سترى هذه الكتل البرمجية في لوحة الكتل البرمجية ضمن الفئة "كتل أخرى More Blocks". شكل3-6 إضافة الموسِّع Pi GPIO إلى سكراتش 2 ابدأ بسحب الكتلة إلى منطقة بناء البرنامج، ثم ضع تحتها الكتلة . عليك الآن اختيار رقم رجل المنصة الذي تستخدمه، لذلك انقر على السهم الصغير المتجه للأسفل في الكتلة السابقة واختر الرقم 25 من القائمة المنسدلة لتخبر سكراتش أنك ستتحكم بالرجل رقم 25 من المنصة. انقر على الراية الخضراء وسترى أنّ المؤشر يضيء، وهكذا ستكون برمجت بنفسك أول مشروع حوسبةٍ فيزيائية. عند النقر على المثمن الأحمر لإيقاف البرنامج لن ينطفئ المؤشر الضوئي، لأنك أنهيت البرنامج دون أن تخبر باي بأن تطفئه؛ فكل ما طلبته منه في برنامجك هو تشغيله من خلال output high أو خرج مرتفع، وهذا يعني أن تقدّم للرجل جهدًا موجبًا يعادل 3.3 فولت في راسبيري. لإطفائه مجددًا انقر على السهم الصغير المتجه للأسفل والمجاور لعبارة "output high" واختر "output low". انقر على الراية الخضراء مجددًا، فسينطفئ المؤشر. لجعل الأمر أكثر متعةً، أضف كتلة حلقةٍ لا متناهية مع كتلتي لبناء برنامجٍ يومض المؤشر باستمرار أي ينطفئ ثانيةً ويضيء ثانية. انقر على الراية الخضراء وراقب كيف سيضيء المؤشر لمدة ثانية ثم ينطفئ لمدة ثانية ويستمر بالوميض باستمرار دون توقف. انقر على المثمن الأحمر لإيقاف البرنامج وتحقق من حالة المؤشر لحظة إيقاف البرنامج فيما إذا كان يضيء أم لا. التحكم بالمؤشر الضوئي باستخدام بايثون افتح برنامج ثوني Thonny انطلاقًا من قائمة راسبيري باي، ثم انقر أيقونة جديد New في شريط أدوات ثوني لإنشاء برنامجٍ جديد، ثم انقر أيقونة Save لحفظ البرنامج باسم "Hello LED". لا بُدّ من استخدام مكتبة GPIO Zero للتعامل مع أرجل المنصة GPIO، لكننا لن نحتاج إلى المكتبة بأكملها في هذا المشروع. أدرج هذا الجزء من المكتبة بكتابة الأمر التالي: from gpiozero import LED انظر المقال السابق البرمجة باستخدام لغة بايثون للتعرف على بيئة ثوني. ستخبر مكتبة GPIO Zero الآن عن الرجل التي يتصل بها المؤشر الضوئي من خلال الشيفرة التالية: led = LED(25) يعطي السطران السابقان بايثون القدرة على التحكم بالمؤشر الضوئي المتصل براسبيري باي، ويخبرانه بالرجل أو الأرجل في حال كنت تتحكم بأكثر من مؤشرٍ في دارتك. اكتب السطر التالي لإضاءة المؤشر: led.on() والسطر التالي لإطفائه: led.off() تهانينا، فأنت تتحكم بأرجل المنصة GPIO باستخدام بايثون. حاول تكرار تعليمتي التشغيل والإطفاء. في حال كان كان المؤشر مطفأً أصلًا، فلن تُنفَّذ التعليمة: led.off() ويحصل الأمر نفسه إذا استخدمت تعليمة تشغيل المؤشر وهو مضاءٌ أصلًا. لجعل برنامجك أكثر واقعية، اكتب الشيفرة التالية: from gpiozero import LED from time import sleep led = LED(25) while True: led.on() sleep(1) led.off() sleep(1) يُدرج هذا البرنامج الدالة LEDمن المكتبة GPIO Zero والدالة sleep من المكتبة time، ثم يبني حلقةً لا متناهية لتكرار إضاءة المؤشر لمدة ثانية ثم إطفائه لمدة ثانية. انقر على أيقونة التشغيل Run لترى المؤشر يومض. راقب حالة المؤشر عند النقر على أيقونة الإيقاف Stop عندما يكون المؤشر مضاءً أو مُطفأً. استخدام لوحة الاختبار المثقبة سيكون المشروع التالي أسهل تنفيذًا في حال استخدمت لوحة اختبارٍ لترتيب وتوصيل العناصر، حيث يغطي وجه لوحة الاختبار الثقوب الموزعة وفق نظامٍ محددٍ لتلائم العناصر، ويتباعد أي ثقبين عن بعضهما مقدار 2.54 ميليمتر. ستجد أسفل هذه الثقوب شرائطًا معدنيةً تصل بين كل مجموعةٍ من الثقوب كما تفعل الوصلات الطرفية التي تعاملنا معها سابقًا. الشكل: لوحة الاختبار المثقبة تصطف الثقوب في صفوفٍ وأعمدة، وتُقسم اللوحة إلى قسمين، أو ثلاثة أقسامٍ منفصلةٍ من الثقوب، وقد تجد على بعض اللوحات أرقامًا من الأعلى للصفوف وأحرفًا على الجانب للأعمدة لتحديد مكان ثقبٍ معيّن؛ حيث ستجد مثلًا الثقب A1 في الصف 1 والعمود الأول A أقصى وأعلى اليسار، والثقب B3 في الصف الثالث والعمود الثاني B، وهكذا. ترتبط الثقوب في كل صفٍ ببعضها عبر شريطٍ معدني مخفي؛ حيث تمثّل بمجموعها نقطة توصيلٍ واحدة، أي أن كل الثقوب التي تحمل الرقم 1 مرتبطةٌ معًا والتي تحمل رقم 2 كذلك؛ بينما لا ترتبط ثقوب الصف 1 مع ثقوب الصف 2 إطلاقًا ما لم يصل بينهما سلكٌ فيتحول الصفّان إلى نقطةٍ واحدة. يمكن أن تضم لوحات الاختبار الكبيرة شريطين جانبيين من كل جهة، معلّمين بخطين أحمر وأسود، أو أحمر وأزرق، وقد صُممت هذه الأعمدة من الثقوب لتسهيل توصيل التغذية الكهربائية إلى بقية الثقوب، حيث يمكن وصل سلكٍ من رجل راسبيري باي "3V3" أو "5V" إلى خط التغذية ذو اللون الأحمر، والإشارة الموجبة وسلك من الرجل GND إلى الخط الأسود أو الأزرق ذي الإشارة السالبة. تجدر الإشارة إلى أن ثقوب الخط الأحمر متصلةٌ معًا وكذلك ثقوب الخط الآخر، ولا يوجد اتصالٌ أبدًا بين الخطين. من السهل إضافة العناصر الإلكترونية إلى لوحة الاختبار، فما عليك فعله هو ثني أرجل العنصر الإلكتروني الطرية ودفعها بلطفٍ في الثقوب المناسبة حتى تأخذ مكانها. استخدم وصلاتٍ طرفية M2M للوصل بين نقطة (صف ثقوب) وأخرى، ومن النوع M2F لوصل نقاطٍ من اللوحة مع أرجل باي. لا تحاول حشر أرجل عدّة عناصرٍ في ثقبٍ واحد؛ وإذا أردت وصلها معًا، فتذكر أن وضعها في صفٍ واحدٍ يجعلها متصلةً معًا بالشريط المعدني المخفي. مراقبة إشارة صادرة عن ضغطة زر إنّ عملية تمرير التيار الكهربائي من باي إلى المؤشر الضوئي والمعروفة بعملية خرج إشارة، هي أحد شقي الوظيفة المختلطة "دخل/ خرج input/output" لبعض أرجل منصة GPIO، حيث يمكن استخدام الرجل نفسها لاستقبال تيار كهربائي، وتُعرف بعملية دخل إشارة إلى باي أيضًا. سنحتاج في هذا المشروع إلى: لوحة اختبار. أسلاك بوصلات طرفية M2M وأخرى M2F. قاطع آني أو زر كبس. يمكن استخدام أسلاك بوصلة طرفية F2F بدلًا من لوحة الاختبار، لكنك ستواجه صعوبة في الضغط على الزر دون أن تتسبب في تفلّت بعض الأسلاك. ابدأ بإضافة الزر إلى اللوحة؛ فإذا كان للزر رجلين فقط، فعليك حشر كل رجلٍ في صفٍ مختل؛ أما إذا كان للزر أربعة أرجل، فاحشر رجلي الطرف الأول في عمودٍ واحد وسيدخُل رجلي الطرف الثاني تلقائيًا في عمودٍ آخر. صل بين رجل الأرضية GND في باي وخط التغذية السالب على لوحة الاختبار باستخدام سلكٍ ذو وصلاتٍ طرفية M2F، ثم صل أحد أرجل الزر بخط التغذية السالبة مستخدمًا سلك M2M، كما هو موضح في الشكل التالي. أخيرًا، صِل الرجل الآخرى للزر إذا كان ذا رجلين، أو الرجل التي تقع على نفس الجانب إذا كان الزر بأربعة أرجل إلى الرجل GP2 في المنصة GPIO. شكل 4-6 توصيل الزر إلى المنصة GPIO مراقبة إشارة صادرة عن ضغطة زر باستخدام سكراتش ابدأ مشروع سكراتش جديد واسحب الكتلة إلى منطقة بناء البرنامج، ثم أضف تحتها الكتلة وغيّر gpio إلى 2 gpio بالنقر على السهم المجاور واختيار هذه القيمة من القائمة المنسدلة ليتطابق مع الرجل التي وصلتها بالزر. انقر كذلك على السهم الصغير بجوار "output high" وحوِّلها إلى "input" لتهيئة الرجل على أنها رجل دخل لاستقبال الإشارات الكهربائية. لن يحدث الآن شيء عند النقر على الراية الخضراء لأنك أخبرت سكراتش باستخدام الرجل GP2 على أنها رجل دخل، لكنك لم تخبرها ما الذي ستفعله عند تلّقي إشارة الدخل؛ لذلك اسحب الكتلة وضعها في نهاية السلسلة، ثم ضع ضمنها الكتلة ابحث عن الكتلةوضعها في الفراغ الذي يأخذ شكل مسدس داخل الجزء ، ثم انقر على السهم الصغير بجوار "gpio" واختر 2 لتخبر الكتلة الشرطية أن تتحقق من دخل الزر رقم 2 في منصة GPIO. اسحب أخيرًا الكتلة وضعها في فراغ الجزء من الكتلة الشرطية، ثم غيِّر الكلمة "!Hello" إلى "!Button pushed"، ودع الجزء فارغ حاليًا. تجري الكثير من الأحداث في الشيفرة السابقة، لكننا سنبدأ باختبارها أولًا. لذلك انقر الراية الخضراء، ثم اضغط الزر على لوحة الاختبار. من المفترض أن تخبرك الشخصية الاعتيادية على مسرح سكراتش وهي القط أنك ضغطت الزر، وبالتالي ستكون قد أنجزت مهمتك بقراءة إشارة دخل وصلت إلى منصة GPIO بنجاح. ربما لاحظت أن ما داخل الجزء من العبارة الشرطية هو المكان الذي يجب أن توضع فيه الشيفرة الفعلية للتعامل مع الضغط على زر الكبس في لوحة الاختبار، إلا أن هذه الشيفرة في الجزء الآخر . سيسبب هذا الأمر ارتباكًا، لأنك تتوقع أن ضغط الزر سينقل رجل المنصة إلى حالة الجهد المرتفع "high"، لكن الحالة المعاكسة هي الصحيحة في راسبيري باي؛ فعندما تخصص رجلًا من أرجل المنصة على أنها رجلٌ لاستقبال إشارة الدخل، فسيصبح جهدها مرتفعًا "high"؛ وعندما نضغط الزر، فإننا في الواقع سنصل رجل الدخل إلى جهد الأرضية GND، أي سنسحب جهده إلى الحالة المنخفضة "low". أمعن النظر في دارتك، ستجد اتصال الرجل GP2 التي تمثّل الجهد الموجب في الدارة مع رجل الأرضية عن طريق زر الكبس، وبالتالي ستصبح صفرًا (حالة منخفضة) عند ضغط الزر ولن يُنفَّذ الجزء من العبارة الشرطية بل الجزء . تذكر دائمًا أن راسبيري باي تستشعر ضغطة الزر عندما تنتقل حالة رجل الدخل من الحالة المرتفعة إلى المنخفضة. سنضيف الآن مؤشرًا ضوئيًا إلى الدارة؛ لذلك صل الرجل GP25 بمقاومة، وصِل طرفها الآخر برجل المؤشر الضوئي الطويلة، ثم صِل أخيرًا رجل المؤشر الأقصر بخط التغذية السالب في لوحة الاختبار. اِسحب الكتلة خارج الكتلة الشرطية واحذفها، ثم أضِف الكتلة إلى الجزء من العبارة الشرطية، وتذكر اختيار العدد 25 بالنقر على سهم القائمة المنسدلة، ثم أضف الكتلة إلى الجزء الآخر . انقر على الراية الخضراء ثم اضغط الزر. لاحظ أنّ المؤشر سيضيء طالما أنك تستمر بالضغط على الزر، وسينطفئ إذا حررته. تهانينا، تستطيع الآن التحكم برجلٍ من أرجل المنصة GPIO بناءً على إشارة دخلٍ تتلقاها رجلٌ أخرى. مراقبة إشارة صادرة عن ضغطة زر باستخدام بايثون انقر على أيقونة جديد New في شريط أدوات ثوني لتُنشئ مشروعًا جديدًا، ثم احفظه باسم "Button Input". سنستخدم رجلًا من GPIO على أنها رجل دخل بنفس طريقة استخدامها مثل رجل خرج، لكننا سنحتاج إلى جزءٍ آخر من المكتبة GPIO Zero، لذلك اكتب الشيفرة التالية: from gpiozero import Button button = Button(2) لجعل شيفرةٍ ما تعمل عند ضغط الزر، سنستخدم الدالة wait_for_press المدمجة مع المكتبة GPIO Zero، لذلك اكتب الشيفرة التالية: button.wait_for_press() print("You pushed me!") انقر على أيقونة التشغيل Run ثم اضغط الزر، فتظهر العبارة "!You pushed me" في نافذة المفسِّر أسفل نافذة ثوني. تهانينا، لقد قرأت بنجاحٍ إشارة الدخل القادمة إلى المنصة GPIO. انقر من جديد على الأيقونة Run إذا أردت اختبار البرنامج مجددًا، لأن شيفرته لا تحتوي حلقاتٍ لمراقبة الزر على الدوام، وسيتوقف كل شيءٍ بمجرد طباعة العبارة الموجودة في نهاية الشيفرة. أعِد توصيل المؤشر الضوئي والمقاومة إذا لم تكن قد فعلت ذلك وفقًا للطريقة المُعتمدة في الفقرة السابقة. ولقراءة دخل الزر وإضاءة المؤشر، لا بدّ من إدراج جزئي المكتبة GPIO Zero المخصصين لذلك. أضِف سطري الشيفرة التاليين إلى بداية البرنامج: from gpiozero import LED from time import sleep ثم أضِف السطر: led = LED(25) بعد السطر: button = Button(2) ثم احذف سطر التعليمة print وضع مكانها الأسطر التالية: led.on() sleep(3) led.off() سيبدو برنامجك الآن على النحو التالي: from gpiozero import LED from time import sleep from gpiozero import Button button = Button(2) led = LED(25) button.wait_for_press() led.on() sleep(3) led.off انقر على أيقونة Run ثم اضغط على الزر، سيضيء المؤشر لثلاث ثوانٍ ثم ينطفئ وينتهي البرنامج. تهانينا، تستطيع الآن التحكم برجلٍ من أرجل المنصة GPIO بناءً على إشارة دخل تتلقاها رجلٌ أخرى باستخدام بايثون. تشغيل منبه صوتي إن التحكم بجهاز للإنذار والتنبيه باستخدام المؤشرات الضوئية أمرٌ عظيم، لكنه لن يخدمك كثيرًا إذا كنت تنظر بالاتجاه الآخر، وسيكون الحل باستخدام منبهٍ صوتي buzzer مسموعٍ في كل أرجاء الغرفة. سنحتاج في هذه الفقرة إلى: لوحة اختبار. أسلاك بوصلات طرفية منوعة M2F وF2F، إذا لم تشأ استخدام لوحة اختبار. منبه صوتي فعّال Active. يُعامل المنبه الصوتي الفعّال مثل المؤشر الصوتي من ناحية التوصيل والبرمجة. استخدم دارة توصيل المؤشر الضوئي نفسها لكن استبدل المؤشر الضوئي بالمنبه ولا تستخدم مقاومة لأن المنبه يحتاج إلى تيارٍ أعلى ليعمل. إذًا، صِل الرجل "GP15" بأحد رجلي المنبه مباشرةً، وصِل الرجل الأخرى له بأحد أرجل الأرضية "GND" للمنصة GPIO؛ أما في الحالة التي يمتلك فيها المنبه ثلاثة أرجل، صِل الرجل المعلّمة بإشارة "+" إلى رجل "3V3" والمعلمة بإشارة "-" إلى رجل أرضية "GND" والثالثة المُعلّمة بالحرف "s" (إشارة signal) إلى الرجل GP15. شكل 5-6 توصيل المنبه الصوتي إلى المنصة GPIO التحكم بالمنبه الصوتي باستخدام سكراتش أنشئ مشروعًا جديدًا مطابقًا لمشروع تشغيل المؤشر الضوئي، أو حمّله إذا كنت قد خزنته، وغيّر رقم الرجل في الكتل ليصبح 15، وبالتالي سيتحكم سكراتش بالرجل GP15. انقر على الراية الخضراء وسيبدأ المنبه بإصدار صوتٍ لمدة ثانية ثم يتوقف لمدة ثانية. إذا لم يصدر سوى صوت نقرةٍ فقط وليس صوتًا متواصلًا خلال فترة تشغيل المنبه، فما تستخدمه هو منبهٌ غير فعّال passive؛ والذي يحتاج إلى إشارةٍ مهتزةٍ مستمرة حتى تتحرّض الصفيحتان المعدنيتان وتهتزان لإنتاج الصوت؛ بينما يولد المنبه الفعّال active إشارةً مهتزةً سريعة بنفسه. عند تنفيذ برنامج سكراتش على منبهٍ غير فعّال، ستهتز الصفيحتان مرةً واحدةً وتتوقفان بعدها، ويصدر صوت النقرة الذي لن يتكرر حتى يبدّل برنامج سكراتش حالة الرجل من منخفضة إلى مرتفعة. انقر الآن على المثمن الأحمر لإيقاف البرنامج، واحرص أن يكون ذلك عندما لا يصدر المنبه صوتًا، وإلا سيستمر في ضجيجه حتى يعمل البرنامج مرةً ثانية. التحكم بالمنبه الصوتي باستخدام بايثون يُعد التحكم بمنبهٍ صوتي مشابهًا تمامًا للتحكم بمؤشر ضوئي عند استخدام المكتبة GPIO Zero، فللمنبه أيضًا حالتان: تشغيل أو إطفاء. سنحتاج بالطبع إلى دالةٍ مختلفة، وهي buzzer. ابدأ مشروعًا جديدًا في ثوني واحفظه باسم Buzzer، ثم اكتب الشيفرة التالية: from gpiozero import Buzzer from time import sleep عليك أيضًا تحديد رجل GPIO التي تتصل بالمنبه الصوتي، حتى تتمكن من التحكم به، لذا اكتب الشيفرة التالية: buzzer = Buzzer(15) تتطابق بقية الشيفرة مع مثيلاتها التي تتحكم بالمؤشر الضوئي ما عدا أنك ستستخدم كلمة "buzzer" بدلًا من "led"، وأنّ رقم رجل GPIO مختلف. اكتب إذًا الشيفرة التالية: while True: buzzer.on() sleep(1) buzzer.off() sleep(1) انقر على أيقونة Run وستسمع مباشرةً صوت المنبه لمدة ثانية ثم يختفي الصوت مدة ثانية، ولن تسمع سوى صوت نقرةٍ وجيزة كل ثانية بدلًا من صوتٍ مستمر في حال استخدمت منبهًا غير فعّال، كونه يفتقر إلى مولد إشارةٍ قادرٍ على توليد إشارةٍ سريعة التغير لإنتاج اهتزازٍ متواصلٍ للصفيحتين المعدنيتين. انقر الآن على المثمن الأحمر لإيقاف البرنامج، واحرص أن يكون ذلك عندما لا يصدر المنبه صوتًا، وإلا سيستمر في ضجيجه حتى يعمل البرنامج مرةً ثانية. المشروع الثاني: إشارات المرور الضوئية لقد اطلعت حتى الآن على طريقة استخدام المؤشرات الضوئية والأزرار والمنبهات الصوتية مثل أجهزة دخلٍ وخرج، لذلك حان الوقت لتستفيد مما تعلمته في مشروع حوسبةٍ فيزيائيةٍ واقعي، وهو مشروع إشارات مرور ضوئية مزودةٍ بزرٍ يمكنك ضغطه لعبور الشارع. ستحتاج في هذا المشروع إلى: لوحة اختبار. ثلاث مؤشرات ضوئية أحمر وأصفر وأخضر. ثلاث مقاومات قيمة كل منها 330 أوم. منبه صوتي. زر. مجموعة من الأسلاك بوصلات طرفية M2M وM2F. لبناء الدارة: صِل المنبه بالرجل "GP15"، والمؤشر الضوئي الأحمر بالرجل "GP25"، والأصفر بالرجل "GP8"، والأخضر بالرجل "GP7"، والزر بالرجل "GP2"، ولا تنس وصل مقاومة 330 أوم بين الرجل الطويلة لكل مؤشرٍ ضوئي ورجل GPIO المتصل بها، ثم صِل الأرجل القصيرة للمؤشرات بخط التغذية السالب على لوحة الاختبار. صِل أخيرًا خط التغذية السالبة بأي رجلٍ أرضية GND من أرجل GPIO باستخدام سلكٍ ذي نهاياتٍ طرفية M2F. شكل 6-6 مخطط التوصيل لمشروع الإشارات الضوئية ابدأ مشروعًا جديدًا في سكراتش 2 ثم اسحب الكتلة إلى منطقة تنفيذ البرنامج. سنخبر سكراتش بعد ذلك بأن الرجل "GP2" المتصلة بالزر هي رجل دخل وليس خرج؛ لذلك اسحب الكتلة من فئة "كتل أخرى More Blocks" إلى أسفل الكتلة . انقر السهم بجوار الرقم 0 واختر الرقم 2، ثم انقر على السهم الصغير الآخر بجوار "output high" واختر "input". سننشئ تاليًا سلسلة الكتل المتحكمة بإشارات المرور، لذلك اسحب الكتلة إلى منطقة بناء البرنامج، ثم ضع داخلها الكتل التي تسمح بتشغيل وإطفاء المؤشرات الضوئية الثلاث وفق نمطٍ محدد، أي كم ثانية سيعمل الأحمر ثم ينطفئ ثم الأصفر ثم الأخضر. لا تنس أنّ المؤشر الأحمر مرتبطٌ بالرجل "GP25" والأصفر بالرجل "GP8" والأخضر بالرجل "GP7". انقر على الراية الخضراء وراقب المؤشرات الضوئية، حيث سيضيء أولًا المؤشر الأحمر ثم كلا المؤشرين الأحمر والأصفر، ثم ينطفئان ليعمل الأخضر ثم الأصفر وتتكرر العملية. يتناسب النمط السابق مع نمط إشارات المرور في المملكة المتحدة، عدّله بما يناسب النمط المستخدم في بلدك إذا أردت. لمحاكاة مرور المشاة، لا بدّ لبرنامجك من مراقبة الزر إذا ضُغط أم لا. أوقف البرنامج بالنقر على المثمن الأحمر في حال كان يعمل. اسحب الكتلة إلى برنامجك لتكون داخل الكتلة مباشرةً، ثم انقل الكتل التي تتحكم بإشارات المرور إلى الجزء ولا تضع شيئًا في الوقت الحالي ضمن الفراغ الذي سيحمل شرط تنفيذ هذا الجزء. لا يغير المشاة الضوء إلى الأحمر بالضغط على الزر ساعة يشاؤون كي يعبروا الشارع، بل سينتظرون تحوُّل الإشارة إلى الأحمر. لبناء ذلك، اسحب كتلة أخرى تليها كتلة ، ثم اسحب كتلة إلى داخلها، وضع المعامل في فراغ الشرط للجزء ، ثم ضع الكتلة ضمن فراغ المعامل. أنشئ أخيرًا متغيرًا جديدًا باسم "pushed"، ثم ضع الكتلة داخل الجزء من الكتلة الشرطية. ستراقب هذه السلسلة من الكتل الحالة التي يُضغط فيها الزر ومن ثم تسند القيمة 1 إلى المتحول pushed، أي ستتذكر أنك ضغطت على الزر دون أن تنفذ شيئًا في الوقت الحالي. عُد إلى السلسلة السابقة من الكتل واسحب العامل إلى داخل فراغ الشرط في الجزء ، ثم اسحب الكتلة إلى فراغ المعامل الأول واكتب 0 في فراغه الآخر. انقر على الراية الخضراء وراقب الإشارات الضوئية. اضغط الزر على لوحة الاختبار، فلن تلاحظ شيئًا للوهلة الأولى؛ لكن عندما ينتهي نمط عمل الإشارات وذلك بإضاءة المؤشر الأصفر، ستنطفئ المؤشرات الضوئية وتبقى على هذا الحال، وذلك بفضل المتغير pushed. يبقى علينا الآن إسناد مهمةٍ أخرى لزر عبور المشاة غير إطفاء الإشارات. اسحب الكتلة إلى داخل الجزء للكتلة الشرطية في تسلسل الكتل الرئيسي، وتذّكر تغيير رقم الرجل ليطابق الرجل الموصولة مع المؤشر الأحمر. ابقى داخل الجزء وانشئ نمطًا لتشغيل المنبه الصوتي وذلك بسحب الكتلة ووضع تسلسل الكتل التالي: ، ثم ، ثم الكتلة ، ثم ضمنها، ولا تنس تغيير رقم الرجل لتلائم تلك المتصلة مع المنبه. أخيرًا، ضع الكتلة مباشرةً تحت الكتلة وبعدها الكتلة التي تغير قيمة المتغير pushed إلى 0 لتنهي حالة ضغط الزر فلا يتكرر تسلسل تشغيل المنبه إلى ما لانهاية. انقر الآن على الراية الخضراء، ثم اضغط الزر على لوحة التحكم، وبعد انتهاء نمط تشغيل الإشارات الضوئية، سيضيء المؤشر الأحمر ويبدأ المنبه بإصدار صوتٍ ينبه المشاة بأن الوضع آمنٌ لعبور الشارع. سيتوقف الصوت بعد ثانيتين وتعود إشارات المرور إلى العمل وفق النمط المحدد. تهانينا، لقد أنجزت برنامجًا يتحكم بمجموعة إشارات مرورية مزودةٍ بآلية لمساعدة المشاة في العبور الآمن. مشروع بلغة بايثون: لعبة سرعة رد الفعل لقد اطلعت حتى الآن على طريقة استخدام المؤشرات الضوئية والأزرار مثل أجهزة دخل وخرج، لذلك حان الوقت لبناء مشروع حوسبةٍ فيزيائيةٍ واقعي، وهو لعبةٌ مؤلفةٌ من لاعبين لقياس سرعة رد فعل كلٍ منهما وتحديد زمن الاستجابة الأسرع. ستحتاج في هذا المشروع إلى: لوحة اختبار. مؤشر ضوئي. مقاومة 330 أوم. زري كبس. بعض الأسلاك ذات الوصلات الطرفية M2F وM2M. سنبدأ بناء الدارة بوصل الزر الأول الذي نضعه على الجانب اليساري للوحة الاختبار مع الرجل "GP14" للمنصة GPIO، والزر الآخر في الجانب اليميني مع الرجل "GP15". نصل بعد ذلك طرف المقاومة بالرجل "GP4" وطرفها الآخر بالرجل الطولية للمؤشر الضوئي. نصل الأرجل الباقية للزرين والمؤشر مع خط التغذية السالب في لوحة الاختبار، ثم نصل الخط مع أي رجلٍ أرضية GND للمنصة GPIO، كما هو موضح في الشكل التالي. شكل 7-6 توصيل عناصر لعبة رد الفعل الأسرع أنشئ مشروعًا جديدًا في ثوني واحفظه باسم"Reaction Game". سنستخدم لكتابة الشيفرة الدالتين LED و button من المكتبة GPIO Zero، والدالة sleep من المكتبة time. سندرج دالتي المكتبة GPIO Zero على سطرٍ واحد باستخدام الفاصلة ",". اكتب الشيفرة التالية: from gpiozero import LED, Button from time import sleep حدد الآن أرجل GPIO المتصلة مع المؤشر الضوئي والزرين، لذلك اكتب الشيفرة التالية: led = LED(4) right_button = Button(15) left_button = Button(14) أضِف بعد ذلك تعليمات تشغيل وإطفاء المؤشر الضوئي للتحقق من عمله: led.on() sleep(5) led.off() انقر على أيقونة التشغيل Run وسترى أن المؤشر سيضيء مدة خمس ثوانٍ ثم ينطفئ وينتهي البرنامج. لكن سيكون إطفاء المؤشر الضوئي بعد 5 ثوانٍ أمرًا متوقعًا في لعبةٍ مثل التي نبنيها، لذلك أضف السطر التالي: from random import uniform بعد السطر: from time import sleep تتيح لك المكتبة random إمكانية توليد أعدادٍ عشوائية وفق قاعدة التوزيع المنتظم uniform distribution)، لذلك استبدل تعليمة (5)sleep بالسطر التالي: sleep(uniform(5, 10)) إذا شغّلت البرنامج مجددًا، سترى أن المؤشر يضيء مدةً عشوائيةً بين خمس وعشر ثوان. جرّب ذلك بتشغيل البرنامج مراتٍ عديدة وقياس مدة الإضاءة في كلِّ مرة. لاحظ كيف ستختلف أزمنة الإضاءة، مما يجعل توقع لحظة توقف المؤشر عن الإضاءة غير متوقعة. سنضيف الآن الدالة المُسماة pressed لتفعيل عمل زري اللاعبين، لذلك اكتب الشيفرة التالية في آخر برنامجك: def pressed(button): print(str(button.pin.number) + " won the game") تميّز بايثون التعليمات الواقعة داخل دالةٍ من خلال إزاحتها إلى اليمين، وهذا ما يفعله ثوني تلقائيًا. أضِف أخيرًا السطرين التاليين لاستشعار ضغط اللاعب على زره: right_button.when_pressed = pressed left_button.when_pressed = pressed لا تزح السطرين السابقين كي لا يعدّهما بايثون جزءًا من الدالة. شغّل البرنامج وحاول هذه المرة الضغط على أحد الزرين في اللحظة التي ينطفئ فيها المؤشر الضوئي، ستظهر عندها رسالةً في نافذة المفسِّر أسفل نافذة ثوني مفادها أن الزر قد ضُغط، لكن ستظهر الرسالة في كل مرةٍ يُضغط فيها أيٌّ من الزرين دون تمييز، وستعرض رقم الرجل التي تلقت إشارة الزر بدلًا من إظهار اسمٍ ملائمٍ للاعب. لتحسين الوضع، سنبدأ بسؤال اللاعبين عن اسميهما، لذلك اكتب الشيفرة التالية: left_name = input("Left player name is ") right_name = input("Right player name is ") تحت السطر: from random import uniform عُد إلى الدالة واستبدل محتواها بالشيفرة التالية: if button.pin.number == 14: print (left_name + " won the game") else: print(right_name + " won the game") شغِّل البرنامج من جديد، ثم اختر اسمين للاعبين وحاول الضغط على الزر بأقصى سرعة عند توقف إضاءة المؤشر. سترى هذه المرة ظهور اسم اللاعب بدلًا من رقم الرجل، لكن ستظهر الرسالة بمجرد ضغطت الزر دون أن تعرف من هو الأسرع. لإصلاح الأمر سندرج الدالة exit من المكتبة "sys" اختصارًا للكلمة System، تحت آخر سطرٍ لإدراج الدوال في برنامجك: from os import _exit اكتب التعليمة التالية في آخر سطرٍ من أسطر الدالة pressed: _exit(0) وانتبه إلى إزاحة التعليمة بمقدار أربع مسافاتٍ فارغة عن بداية تعريف الدالة لأنها جزءٌ منها. ستنهي هذه التعليمة البرنامج بمجرد أن يُضغط أحد الزرين، وبالتالي يفوز اللاعب الذي يضغط أولًا. سيبدو برنامجك بشكله النهائي على النحو التالي: from gpiozero import LED, Button from time import sleep from random import uniform from os import _exit left_name = input("Left player name is ") right_name = input ("Right player name is ") led = LED(4) right_button = Button(15) left_button = Button(14) led.on() sleep(uniform(5, 10)) led.off() def pressed(button): if button.pin.number == 14: print(left_name + " won the game") else: print(right_name + " won the game") _exit(0) right_button.when_pressed = pressed left_button.when_pressed = pressed شغِّل البرنامج واختر اسمين للاعبيك، ثم انتظر حتى ينطفئ الضوء واضغط على الزرين بأقصى سرعة، فسيظهر فقط اسم اللاعب الأسرع الذي حقق الفوز. ستشاهد أيضًا في نافذة المفسِّر سطرين تظهرهما بايثون، أولهما (Backend terminated (returncode: 0؛ والذي يعني أن بايثون تلّقى الأمر (exit(0_ وأوقف البرنامج، والثاني . . . Use 'Stop/Restart' to restart the backend؛ والذي يخبرك أن البرنامج قد أُوقِف وعليك النقر على أيقونة الإيقاف Stop لإنهائه. شكل 8-6 حالما يتحدد الفائز عليك إيقاف برنامجك تهانينا، لقد أنجزت لعبةً إلكترونيةً حقيقية. ترجمة -وبتصرف- للفصل السادس "Physical computing with scratch and python" من كتاب The official Raspberry Pi beginner's guide. اقرأ أيضًا المقال السابق: البرمجة باستخدام لغة بايثون في تطبيقات راسبيري باي تجميع راسبيري باي والتحضير لاستعماله إنشاء لعبة أضواء باستخدام برنامج سكراتش وحاسوب راسبيري باي لعبة تخفيف التوتر باستخدام سكراتش وحاسوب راسبيري باي تصميم لعبة السلك والحلقة باستخدام برنامج سكراتش وحاسوب راسبيري باي
  20. تحتوي كل متصفحات الويب الحديثة مجموعة أدوات فعّالة لمطوري الويب تنفذ مجالًا واسعًا من الوظائف من فحص ملفات HTML وCSS وجافاسكريبت إلى عرض ملف دعم طلبته الصفحة والمدة التي يستغرقها حتى يُحمّل. يشرح هذا المقال كيفية استعمال الوظائف الأساسية لأدوات مطوري ويب DevTools الخاصة بمتصفحك. فتح أدوات مطوري ويب في متصفح ستجد أدوات مطوري الويب ضمن نافذة فرعية تبدو نوعًا ما كالصورة التالية وذلك بحسب المتصفح الذي تستخدمه. لكن كيف ستظهر هذه الأدوات؟ باستخدام لوحة المفاتيح: اضغط على الأزرار CTRL + Shift + I، ماعدا المتصفحات التالية: مايكروسوفت إنترنت إكسبلورر وإيدج: اضغط على F12. ماك أو إس: اضغط على ⌘ + ⌥ +I. باستخدام شريط القائمة Menu Bar: اضغط زر القائمة ثم: فايرفوكس: اضغط على "مطوري ويب Web Developer" ثم اختر "تبديل الأدوات Toggle Tools" أو "أدوات Tools" ثم اختر "مطوري الويب Web Developer" ثم اختر "تبديل الأدوات Toggle Tools". كروم: اضغط على "المزيد من الأدوات More Tools" ثم اختر "أدوات المطورين Developer Tools". سفاري: اضغط على "تطوير Develop" ثم اختر "إظهار فاحص الويب Show Web Inspector"، وإن لم تجد قائمة "تطوير Develop" انتقل إلى المتصفح سفاري Safari ثم اختر "تفضيلات Preferences" ثم اختر "متقدم Advanced" ثم فعّل الخيار "أظهر قائمة التطوير في شريط القائمة Show Develop menu in menu bar". أوبرا: اضغط على "مطورون Developer" ثم اختر "أدوات المطورين Developer tools". باستخدام قوائم السياق Context Menu: اضغط باستمرار بالزر الأيمن للفأرة على أي عنصر في صفحة الويب (انقر CTRL في ماك) واختر "فحص عنصر Inspect Element" من قائمة السياق التي ستظهر (فائدة إضافية: تظلل هذه الطريقة مباشرة شيفرة العنصر الذي نقرت عليه). فحص شجرة العناصر DOM ومحرر تنسيقات CSS تُظهر أدوات مطوري ويب عند فتحها نافذة الفاحص Inspector افتراضيًا والذي يبدو تقريبًا كما تعرضه لقطة الشاشة التالية: تعرض هذه الأداة نتيجة شيفرة HTML في زمن التنفيذ، كما تعرض تنسيقات CSS المطبقة على كل عنصر من عناصر الصفحة. تتيح لك الأداة أن تعدّل عناصر HTML وCSS أيضًا، وأن تشاهد أثر التغييرات التي أحدثتها مباشرة في المتصفح. إن لم تظهر نافذة الفاحص مباشرة: اضغط أو المس النافذة "فاحص Inspector" في فايرفوكس. اضغط أو المس النافذة "مستكشف DOM Explore" أو اضغط CTRL + 1 في إنترنت إكسبلورر. اضغط أو المس النافذة "عناصر Elements" في مايكروسوفت إيدج وأوبرا وكروم. لا تظهر عناصر التحكم بصورة واضحة في سفاري، لكن من المفترض أن ترى نافذة HTML إن لم تختر شيئًا آخر. اضغط على زر "تنسيق Style" لعرض تنسيقات CSS. استكشاف عمل فاحص DOM انقر في البداية بالزر اليميني للفأرة (أو اضغط CTRL) على عنصر HTML ضمن فاحص شجرة DOM وتحقق من محتويات قائمة السياق التي ستظهر. تختلف عناصر القائمة من متصفح لآخر، لكن المهمة منها موجودة غالبًا في جميع المتصفحات. حذف عقدة Delete Node: (تجدها أحيانًا "حذف عنصر Delete Element") تحذف العنصر المحدد. تحرير كملف HTML: (تجده أحيانًا "إضافة سمة Add Attribute/‎ تحرير نص Edit Text") وذلك لتعديل ملف HTML ومشاهدة نتيجة التعديلات مباشرة، وهو مفيد جدًا للتنقيح والاختبار. تمرير Hover/‎ تفعيل Active/‎ تركيز Focus: تجبر العنصر على تغيير الحالة التي يُعرض بها، وبالتالي ستتمكن من مشاهدة تنسيقه في كل حالة. نسخ Copy/‎ نسخ بصيغة HTML: عنصر HTML الذي تختاره. يمكن أن تجد في بعض المتصفحات خيارات مثل "نسخ CSS" و"نسخ Xpath" لكي تنسخ مُحدِّد CSS أو تعبير Xpath المرتبط بعنصر HTML الحالي. حاول أن تعدّل في شجرة DOM، انقر نقرًا مزدوجًا على عنصر ثم انقر بالزر اليميني عليه واختر "تحرير كملف HTML" من قائمة السياق التي تظهر. يمكنك إحداث التغييرات التي تريد لكن ليس بالإمكان حفظ هذه التغييرات. استكشاف محرر تنسيقات CSS يعرض محرر CSS افتراضيًا القواعد المطبقة على العنصر المختار: تُساعدك هذه الميزات في النقاط التالية: عرض قواعد CSS المطبقة على العنصر الحالي مرتبة من الأكثر تخصيصًا لهذا العنصر إلى الأقل. عرض ما يحدث عند حذف تصريح ما، ولكن لا بدّ أن تنقر قبل ذلك على صندوق التحقق الموجود إلى جوار التصريح. عرض المكافئات الطويلة لخاصية محددة عند النقر على السهم الصغير الموجود إلى جوارها. عرض نتيجة تغيير التنسيق مباشرة بعد وضع قيم جديدة للخاصيات. انقر على اسم الخاصية أو قيمتها ليظهر لك مربع نص ثم اكتب ضمنه القيمة الجديدة. ستجد إلى جانب قاعدة اسم الملف ورقم السطر الذي عُرِّفت القاعدة ضمنه. انقر على القاعدة لتنتقل إلى عرض القاعدة في مكان وجودها الأصلي حيث يمكنك عادةً تعديلها وحفظ التعديلات التي أجريتها. يمكنك أن تنقر أيضًا على القوس المعقوص لأي قاعدة لإظهار مربع نص ضمن سطر جديد إذ يمكنك كتابة قاعدة جديدة كليًا وفقًا لما تحتاج. لاحظ وجود عدة نوافذ فرعية يمكن النقر عليها في نافذة CSS: التنسيق المحوسب Computed: وتعرض لك التنسيق كما هو مطبق على العنصر (القيم النهائية الجاهزة للتطبيق ضمن المتصفح). عرض المخطط Layout: تتكون هذه المنطقة في فايرفوكس من: نموذج صندوقي Box Model: ويعرض نموذجًا صندوقيًا بصريًا لخصائص العنصر لتتمكن مباشرة من الاطلاع على الهوامش والحدود والمساحات الفارغة حوله، وحجم المحتوى الذي يضمه. شبكة العرض Grid: إن استخدام تنسيق الشبكة CSS Grid ضمن الصفحة التي تتفحصها، سيساعدك هذا القسم على رؤية تفاصيل هذه الشبكة. الخطوط Fonts: وتظهر الخطوط المطبقة على العنصر. منقح جافاسكربت يتيح منقح جافاسكربت مراقبة قيمة المتغيرات وضبط نقاط إيقاف التنفيذ Breakpoints، وهي أماكن في شيفرتك تريد إيقاف تنفيذ الشيفرة عندها لتتحقق من المشاكل التي تمنع الشيفرة من العمل بالطريقة المطلوبة. للوصول إلى المنقح: فايرفوكس: اضغط على زر القائمة ثم اضغط على "أدوات المطور Web Developer" ثم اضغط على "المنقح Debugger". كما يمكن الضغط على المفاتيح CTRL + Shift + I معًا. وإن كانت أدوات تطوير ويب مفتوحة مسبقًا، اضغط فقط على نافذة "المنقح Debugger". إنترنت إكسبلورر 11 وإيدج: اضغط على المفتاح F12 ثم المفتاحين CTRL + 3. إن كانت أدوات مطوري ويب مفتوحة مسبقًا، انقر على نافذة "المنقح Debugger". سفاري: افتح نافذة أدوات مطور ويب ثم اضغط على نافذة "المنقح Debugger". استكشاف منقح جافاسكربت ستجد ثلاثة أقسام في منقح جافاسكربت على فايرفوكس قائمة الملفات وهو القسم الأول على يسار نافذة المنقح، يتضمن لائحة الملفات المرتبطة بالصفحة التي تنقحها. اختر الملف الذي ترغب بالعمل عليه بالنقر عليه لتظهر محتوياته ضمن القسم الأوسط من نافذة المنقح. الشيفرة المصدرية وتساعدك في وضع نقاط إيقاف التنفيذ أينما ترغب في ملف الشيفرة. لاحظ نقطة الإيقاف في الصورة التالية، وهي عند السطر المظلل الذي يحمل الرقم 18: مراقبة التعابير ونقاط إيقاف التنفيذ تعرض لك هذه الأداة العبارات التي أضفتها ونقاط إيقاف التنفيذ التي وضعتها، وهي موجودة على يمين نافذة المنقح. تُرتّب نقاط إيقاف التنفيذ في القسم الثاني "نقاط إيقاف التنفيذ Breakpoints". لاحظ كيف وضعت نقطة إيقاف في ملف الشيفرة "example.js" قبل السطر البرمجي: listItems.push(inputNewItem.value); يظهر القسمان الأخيران فقط عند تنفيذ الشيفرة. إذ يعرض القسم "مكدس الاستدعاءات Call Stack" الشيفرة التي جرى تنفيذها حتى الوصول إلى السطر الحالي. لاحظ أنّ الشيفرة موجودة في الدالة التي تعالج نقرة الفأرة، وأن الشيفرة في حالة إيقاف بفعل نقطة الإيقاف. وأخيرًا يعرض القسم "المجالات Scopes" القيم المختلفة التي تنتجها الشيفرة وبالإمكان متابعتها. تعرض الصورة التالية على سبيل المثال الكائنات الموجودة في الشيفرة إضافة إلى الدالة "AddItemClick". طرفية جافاسكربت وهي أداة غاية في الفائدة لتنقيح ملفات جافاسكربت التي لا تعمل كما هو متوقع. تسمح لك الأداة بتنفيذ أسطر الشيفرة بالموازنة مع الصفحة التي يعرضها المتصفح، وتبلغك بالأخطاء التي يصادفها المتصفح عندما يحاول تنفيذ الشيفرة. للولوج إلى طرفية جافاسكربت المدمجة مع المتصفح: إن كانت نافذة أدوات مطوري ويب مفتوحة انقر على نافذة "طرفية Console"، وإن لم تكن مفتوحة يمكنك في فايرفوكس الضغط على المفاتيح CTRL + SHIFT + K معًا أو من خلال: اضغط على رمز القائمة ثم اضغط على "أدوات المطورين Web Developer" ثم اضغط على "طرفية ويب Web Console" أو "أدوات Tools" ثم اضغط على "أدوات المطورين Web Developer" ثم اضغط على "طرفية الويب Web Console". في بقية المتصفحات، افتح نافذة أدوات مطوري ويب ثم انقر على نافذة الطرفية. ينتج عن فتح الطرفية نافذة مشابهة للنافذة في الصورة التالية: لتختبر الطرفية، حاول كتابة مقطع الشيفرة التالي ضمنها مقطعًا مقطعًا (ثم اضغط "Enter"). لنكتب أولًا التعليمة التالية: alert('hello!'); ثانيًا جرب كتابة الشيفرة التالية: document.querySelector('html').style.backgroundColor = 'purple'; const myWordmark = document.createElement('img'); myWordmark.setAttribute('src','https://blog.mozilla.org/press/wp-content/themes/OneMozilla/img/mozilla-wordmark.png'); document.querySelector('h1').appendChild(myWordmark); حاول الآن إدخال نسخة خاطئة من الشيفرة وراقب ما يحدث: alert('hello!); أو هكذا: document.cheeseSelector('html').style.backgroundColor = 'purple'; const myWordmark = document.createElement('img'); myBanana.setAttribute('src','https://blog.mozilla.org/press/wp-content/themes/OneMozilla/img/mozilla-wordmark.png'); document.querySelector('h1').appendChild(myWordmark); ستبدأ بملاحظة طبيعة الأخطاء التي يعيدها المتصفح. يمكن أن تكون هذه الأخطاء مشفرة، ولكن من السهل تحليلها وإيجاد المشاكل الكامنة وراءها. ترجمة -وبتصرف- للمقال How does the Internet work. اقرأ أيضًا مدخل إلى أدوات التطوير في متصفح الويب DevTools أدوات المطور ما هي الأدوات المستخدمة في بناء مواقع ويب؟ كيف تستخدم أدوات المطوِّر في المتصفحات الحديثة كيف تستخدم أدوات المطور DevTools في Chrome
  21. سنلقي الضوء في هذا المقال على بعض الأشياء التي ينبغي التفكير بها عند تثبيت محرر نصوص لتطوير مواقع الويب. ننصحك قبل الشروع بقراءة المقال أن تطلع على مقال ما هي الأدوات المستخدمة في بناء مواقع ويب؟ مقدمة عن المحررات البرمجية لتطوير الويب تتكون مواقع الويب في معظمها من ملفات نصية، ولكي تختبر تجربة مريحة وممتعة في رحلة تطوير موقع ويب، لا بدّ من اختيار محرر النصوص بحكمة! ستجد عددًا كبيرًا من محررات النصوص لكونها أمرًا أساسيًا في علوم الحاسوب (وبالطبع تطوير الويب جزء من علوم الحاسوب). عليك -إن أردنا التكلم بمثالية- أن تجرب أكبر عدد ممكن من المحررات ثم تختار ما تشعر أنه المناسب لاحتياجاتك، لكننا سنحاول إرشادك لتبدأ بطريقة صحيحة. إليك بعض التساؤلات الأساسية التي ينبغي أخذها بعين الاعتبار: أي نظام تشغيل سأعمل عليه؟ ما هي التقنيات التي أريد أن أتعامل معها؟ ما الميزات الأساسية التي أتوقع وجودها في محرر النصوص؟ هل أريد إضافة ميزات إضافية إلى محرر النصوص؟ هل أحتاج إلى دعم أو مساعدة أثناء استخدام محرر النصوص؟ هل يهمني مظهر محرر النصوص وشعوري عند العمل عليه؟ لاحظ أننا لم نذكر التكلفة وهي أمر هام بكل وضوح، لكن تكلفة المنتج لا ترتبط بالضرورة بجودته أو إمكاناته. ويمكن جدًا تجد محرر نصوص مجاني ومناسب. إليك قائمة ببعض المحررات الأكثر شعبية: 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; } المحرر رخصة الاستخدام السعر نظام التشغيل آلية دعم المنتج توثيقات المنتج قابل للتوسّع Atom MIT/BSD مجاني ويندوز، ماك، لينوكس منتديات دليل استخدام على الإنترنت نعم Bluefish GPL 3 مجاني ويندوز، ماك، لينوكس قوائم بريدية، مستندات تعاونية wikis دليل استخدام على ويب نعم Brackets MIT/BSD مجاني ويندوز، ماك، لينوكس منتديات، محادثة عبر الإنترنت IRC مستندات تعاونية على غت-هاب GitHub Wiki نعم Coda مغلق المصدر $99 ماك تويتر، منتديات، بريد إلكتروني كتاب إلكتروني نعم CodeLobster مغلق المصدر مجاني ويندوز، ماك، لينوكس منتديات، بريد إلكتروني) دليل استخدام على الإنترنت نعم Emacs GPL 3 مجاني ويندوز، ماك، لينوكس الأسئلة الأكثر شيوعًا، قوائم بريدية، مجموعات إخبارية دليل استخدام على الإنترنت نعم Espresso مغلق المصدر $75 ماك الأسئلة الأكثرشيوعًا، البريد الإلكتروني لا توجد توثيقات موجهة إلى المستخدم النهائي، فقط توثيقات للإضافات plug-in doc نعم Gedit GPL مجاني ويندوز، ماك، لينوكس قوائم بريد إلكتروني، محادثات عبر الإنترنت دليل استخدام على الإنترنت نعم Kate LGPL, GPL مجاني ويندوز، ماك، لينوكس قوائم بريد إلكتروني، IRC دليل استخدام على الإنترنت نعم Komodo Edit MPL مجاني ويندوز، ماك، لينوكس منتديات دليل استخدام على الإنترنت نعم Notepad++ GPL مجاني ويندوز منتديات Wiki نعم PSPad مغلق المصدر مجاني ويندوز FAQ، منتديات مساعدة عبر الإنترنت نعم Sublime Text مغلق المصدر $70 ويندوز، ماك، لينوكس منتديات رسمية،غير رسمية نعم TextMate مغلق المصدر $50 ماك تويتر، محادثة عبر الإنترنت، قوائم بريد إلكتروني، بريد إلكتروني دليل استخدام على الإنترنت، مستندات تعاونية نعم TextWrangler مغلق المصدر مجاني ماك الأسئلة الأكثر شيوعًا، منتديات دليل استخدام PDF لا Vim رخصة مصدر مفتوح خاصة مجاني ويندوز، ماك، لينوكس قوائم بريد إلكتروني دليل استخدام على الإنترنت نعم Visual Studio Code مفتوح المصدر خاضع لرخصة MIT/ (رخصة خاصة بالمنتج) مجاني ويندوز، ماك، لينوكس الأسئلة الأكثر شيوعًا توثيق نعم سنلقي نظرة في الفقرات التالية على بعض النقاط التي يجب أن نأخذها بعين الاعتبار عند اختيار محرر نصي. معايير الاختبار ولكن ما الذي عليك التفكير به عند اختيار محرر نصي؟ هيا بنا لنخوض أكثر في التفاصيل. نظام التشغيل الذي تعمل عليه بالرغم من أن الموضوع ما هو إلا تفضيلات شخصية، ولكن تذكر أن بعض المحررات متاحة فقط لأنظمة تشغيل محددة. وإن أردت التنقل من نظام تشغيل إلى آخر، سيحد ذلك من خياراتك. تسهل عليك محررات النصوص التي تعمل عبر المنصات المختلفة Cross-Platform في هذه الحالة أمر الانتقال من نظام إلى آخر. تأكد في البداية من نظام التشغيل الذي تستخدمه ثم اعثر على محرر نصوص يدعمه. تحدد محررات النصوص على مواقعها الإلكترونية الأنظمة التي تدعمها، يمكن ألّا تدعم بعضها سوى إصداراتٍ معينة من أنظمة التشغيل (ويندوز 7 وما بعد وليس فيستا مثلًا). إن كنت تعمل على نظام التشغيل أوبونتو فمن الأفضل البحث ضمن مركز برامج أوبونتو Ubuntu Software Center. إنّ عالم أنظمة التشغيل لينوكس/ يونكس واسع ومتنوع ويمكن ألّا تتوافق حزم البرمجيات بين توزيعة وأخرى. وبالتالي إن وقع اختيارك على محرر نصوص معين لا تدعمه توزيعة لينكس التي تعمل عليها، عليك ترجمة الشيفرة المصدرية للبرنامج بنفسك لتناسب توزيعتك (وهذا عمل للمتمرسين وليس لضعاف القلوب!). التقنيات التي أريد التعامل معها يمكن لأي محرر نصوص أن يقرأ ويحرر أي نص عمومًا. وهذا أمر جيد إن أردت أن تترك لنفسك ملاحظات هنا وهناك، لكن عند تطوير مواقع ويب وكتابة شيفرات HTML وCSS وجافاسكربت، يمكن أن يصل بك الأمر إلى كتابة ملفات كبيرة ومعقدة. لهذا وفر على نفسك العناء واستخدم محرر نصوص يفهم التقنيات التي تتعامل معها. تساعدك الكثير من المحررات النصية في هذا الأمر من خلال مميزاتها التي تقدمها مثل: تلوين العبارات البرمجية Syntax Highlighting: سيغدو الملف أكثر وضوحًا عند تلوين شيفرات الأوامر والكلمات المفتاحية بألوان مختلفة تناسب التقانة التي تستخدمها. الإكمال التلقائي للشيفرة Code Completion: توفر عملية الإكمال التلقائي للبنى البرمجية التي تكتب شيفرتها الوقت كأن يغلق المحرر واسمات HTML المفتوحة، أو أن يقترح عليك خاصية معينة عند كتابة تنسيق CSS. استخدام مقاطع شيفرة (أو قصاصات برمجية) Code Snippets: تستخدم العديد من التقنيات هيكلية متشابهة عند كتابة مستنداتها كما تلاحظ عند كتابة مستندات HTML. لذلك عند استخدامك لمقاطع شيفرة جاهزة سيوفر عليك عناء إعادة كتابتها مرة تلو الأخرى. تدعم معظم محررات النصوص حاليًا تلوين العبارات البرمجية، ولا تدعم بالضرورة الميزتين الباقيتين. لذلك تأكد قبل كل شيء من دعم المتصفح الذي ستعتمده ميزة تلوين العبارات البرمجية لكل من HTML وCSS وجافا سكربت. الميزات الأساسية التي تتوقع أن تجدها في محرر النصوص يعتمد ذلك على احتياجاتك ومخططاتك. إليك بعض الميزات الوظيفية التي تساعدك غالبًا في عملك: البحث والاستبدال في مستند أو أكثر اعتمادًا على التعابير النمطية Regular Expressions أو غيرها من العبارات التي تحتاجها. الانتقال السريع إلى سطر محدد. عرض قسمين من ملف طويل معًا. عرض شيفرة HTML التي تكتبها كما ستظهر على المتصفح. اختيار عدة أسطر من أماكن مختلفة معًا. إظهار مجلدات مشروعك وما تحويه من ملفات. التنسيق التلقائي لشيفراتك باستخدام محسنات مظهر الشيفرة Code Beautifier. التدقيق الإملائي. الإزاحة التلقائية للشيفرة وفقًا لإعدادات الإزاحة. إمكانية إضافة ميزات إضافية إلى المحرر تأتي بعض المحررات القابلة للتوسيع مع عدد قليل من الميزات المدمجة، ويمكن توسيع إمكاناتها بميزات إضافية وفقًا لاحتياجاتك. إن لم تكن متأكدًا من المميزات التي تحتاجها أو افتقر محررك لهذه المميزات، عليك البحث عن محرر قابل للتوسع. وأفضل المحررات هي التي تزودك بالعديد من الإضافات وتقدم لك طريقة للبحث عن هذه الإضافات وتثبيتها تلقائيًا (نتكلم عن محرر مثالي هنا). إن رغبت باستخدام الكثير من الميزات الوظيفية التي أبطأت محررك نظرًا لزيادة الإضافات التي ثبّتها، جرّب استخدام بيئة تطوير متكاملة Integrated Development Environment واختصارًا IDE. تؤمن لك هذه البيئات الكثير من الأدوات ضمن واجهة واحدة، وعلى الرغم من صعوبتها على المبتدئين تبقى خيارًا قائمًا إن شعرت أن محررك محدود القدرة. إليك بعض بيئات العمل المتكاملة: Aptana Studio. Eclipse. Komodo IDE. NetBeans IDE. Visual Studio. WebStorm. الحاجة إلى الدعم أو المساعدة أثناء استخدام المحرر من الجيد أن تعلم إن كنت ستتلقى مساعدة أو دعمًا عندما تستخدم برنامجًا معينًا. تحقق من أمرين اثنين عندما يتعلق الأمر بمحرر النصوص: المحتوى الموجه للمستخدم (الأسئلة الأكثر شيوعًا ودليل المستخدم والمساعدة المباشرة عبر الإنترنت). النقاشات مع المطورين ومستخدمين آخرين (المنتديات والبريد الإلكتروني ومحادثات عبر الإنترنت IRC). استخدم التوثيق المكتوب عندما ترغب في تعلم استخدام محرر النصوص، وتواصل مع الآخرين إن واجهت مشاكل في تثبيت البرنامج أو أثناء استخدامه. أهمية مظهر المحرر وتجربة استخدامه بالرغم من أن الأمر مجرد تفضيلات شخصية إلّا أنه يمكن أن يرغب البعض في تخصيص كل تفصيل في واجهة المستخدم ابتداءً بالألوان وانتهاءً بمواقع الأزرار. تتنوع المحررات النصية تبعًا لهذا المنظور، لذا تحقق من ذلك أولًا. لن تجد صعوبة في إيجاد محرر نصوص يغير سماته اللونية، لكن إن أردت تفاصيلًا أكثر خصوصية لن تجد مفرًا من استخدام IDE. تثبيت المحرر وإعداده للعمل لن تجد أي تعقيدات في تثبيت محرر النصوص، لكن طريقة التثبيت ستختلف من منصة لأخرى، ولا ينبغي أن تكون صعبة إطلاقًا: ويندوز: ستجد ملف التثبيت بإحدى اللاحقتين exe. أو msi. ويأتي البرنامج مضغوط ضمن أرشيف مثل zip. أو 7z أو rar.، وعليك في هذه الحالة تثبيت برنامج إضافي لاستخراج البرنامج من الأرشيف المضغوط. يدعم ويندوز zip. افتراضيًا، فلا حاجة لتثبيت أية برامج إضافية. ماك: يمكنك تنزيل ملف التثبيت ذو اللاحقة dmg. من موقع الويب الخاص بالمحرر، كما ستجد الكثير من المحررات النصية ضمن متجر آبل مما يسهِّل عملية التثبيت. لينوكس: بإمكانك الانطلاق من الواجهة الرسومية لبرنامج مدير الحزم Packet Manager في التوزيعات الأكثر شعبية من لينوكس مثل Ubuntu Software Center أو Mintinstall أو Gnome Software وغيرها من البرامج. ستجد أيضًا ملفًا لاحقته deb. أو rpm. للبرنامج في مرحلة ما قبل التجميع أو الحزم Prepackaging، لكنك ستستخدم في غالب الأحيان خادم المستودعات Repository Server الخاص بالتوزيعة التي تعمل عليها، أما الحالة الأسوء فهي ترجمة الملفات المصدرية للمحرر ليعمل على توزيعتك. خذ وقتك في قراءة تعليمات التثبيت التي يوفرها موقع ويب الخاص بالمحرر. يستمر نظام التشغيل في فتح الملفات النصية باستخدام محرر النصوص الافتراضي حتى تغير ارتباط الملف File Association. ويعني ذلك تحديد المحرر المفضل الذي يستخدمه نظام التشغيل في فتح الملف النصوص عند النقر المضاعف عليه. بعد أن تُثبت المحرر النصوص الذي يلبي احتياجاتك، لا بدّ من وضع اللمسات الأخير على بيئتك الأساسية لتطوير مواقع ويب، أو يمكنك أن تكتب بنفسك شيفرة أول صفحة ويب إن أردت استخدام بيئة عملك مباشرة. ترجمة -وبتصرف- للمقال What text editors are available. اقرأ أيضًا ما هو عنوان URL في الويب؟ ما التكلفة المادية الكاملة لبناء موقع ويب؟ مفهوم الروابط التشعبية في مواقع الويب
  22. سنغطي في هذا الفصل التوابع المتنوعة التي تعمل مع التعابير النمطية بشيء من التفصيل بعد أن غطينا موضوع التعابير النمطية تغطية شاملة بدءًا من مقال أساسيات التعابير النمطية وحتى مقال كتابة تعابير نمطية متقدمة (إن لم تتطلع عليها، فننصحك بالرجوع إليها أولًا). التابع (str.match(regexp يبحث هذا التابع عن تطابقات للتعبير regexp في النص str، وله ثلاثة أنماط: النمط الأول، الراية g غير مفعّلة: يعيد التابع التطابق الأول ضمن مصفوفة، تحوي مجموعات ملتقطةً capturing groups وخصائص، هي موقع التطابق index، والنص الذي نبحث فيه input، وهو النص str. let str = "I love JavaScript"; let result = str.match(/Java(Script)/); alert( result[0] ); // JavaScript (تطابق كامل) alert( result[1] ); // Script (المجموعة الملتقطة الأولى) alert( result.length ); // 2 // Additional information: alert( result.index ); // 7 (موقع التطابق) alert( result.input ); // I love JavaScript (النص الأصلي) النمط الثاني، الراية g مفعلة: سيعيد التابع مصفوفةً تضم كل التطابقات الموجودة في صيغة قيم نصية، دون مجموعات ملتقطة، أو غيرها من التفاصيل. let str = "I love JavaScript"; let result = str.match(/Java(Script)/g); alert( result[0] ); // JavaScript alert( result.length ); // 1 النمط الثالث، إذا لم يوجد تطابق فسيعيد التابع القيمة null، سواء استخدمنا الراية g أم لم نستخدمها، انتبه جيدًا إلى أنه لا يعيد مصفوفةً فارغةً عندما لا يجد تطابقات، بل يعيد القيمة null: let str = "I love JavaScript"; let result = str.match(/HTML/); alert(result); // null alert(result.length); // Error إذا أردنا الحصول على النتيجة في مصفوفة، فيمكننا كتابة الشيفرة على الشكل: let result = str.match(regexp) || []; التابع (str.matchAll(regexp يمثل التابع نسخةً محدثةً ومطورةً عن التابع str.match، ويستخدَم لإيجاد جميع التطابقات وفق المجموعات المحددة، ويختلف عن التابع str.match في ثلاثة أمور، هي: لا يعيد مصفوفةً بل كائنًا قابلًا للتكرار iterable object، ويمكن إنشاء مصفوفة نظامية منه باستخدام Array.from. عند استخدام الراية g يعيد كل تطابق في مصفوفة تحتوي مجموعات. عندما لا يجد تطابقات فلا يعيد null، بل كائنًا فارغًا قابلًا للتكرار. أمثلة عن استخدامه: let str = '<h1>Hello, world!</h1>'; let regexp = /<(.*?)>/g; let matchAll = str.matchAll(regexp); alert(matchAll); // ليس مصفوفة بل كائن matchAll = Array.from(matchAll); // الآن مصفوفة let firstMatch = matchAll[0]; alert( firstMatch[0] ); // <h1> alert( firstMatch[1] ); // h1 alert( firstMatch.index ); // 0 alert( firstMatch.input ); // <h1>Hello, world!</h1> إذا استخدمنا الحلقة for..of للحصول على تطابقات matchAll، فلن نحتاج إلى تحويل الكائن إلى مصفوفة من خلال Array.from. التابع (str.split(regexp|substr, limit يقسم النص وفقًا لتعبير نمطي (أو نص فرعي)، ويمكن استخدامه دون نص بالشكل التالي: alert('12-34-56'.split('-')) // array of ['12', '34', '56'] كما يمكن التقسيم وفقًا لتعبير نمطي بنفس الأسلوب: alert('12, 34, 56'.split(/,\s*/)) // array of ['12', '34', '56'] التابع (str.search(regexp يعيد التابع موقع التطابق الأول، أو يعيد 1- إذا لم يجد تطابقًا: let str = "A drop of ink may make a million think"; alert( str.search( /ink/i ) ); // 10 (first match position) المحدودية الأكبر للتابع هي إيجاده لأول تطابق فقط. فإذا أردنا مواقع بقية التطابقات فلا بدّ من استخدام طرق أخرى، مثل البحث عن جميع التطابقات باستخدام matchAll. التابع (str.replace(str|regexp, str|func وهو التابع الأساسي للبحث والاستبدال، والأكثر فائدةً، ويمكن استخدامه للبحث عن أجزاء من النص دون الحاجة لتعابير نمطية. // بدل الشرطة القصيرة بنقطتين متعامدين alert('12-34-56'.replace("-", ":")) // 12:34-56 مع ذلك قد يصعب استخدامه أحيانًا. عندما يكون المعامل الأول replace نصًا فسيستبدل التطابق الأول فقط حيث ستلاحظ في المثال الأول استبدال الشرطة القصيرة الأولى فقط بالنقطتين المتعامدتين، ولإيجاد بقية التطابقات واستبدالها، لا بدّ من استخدام التعبير النمطي g/-/ بدلًا من النص "-"، مع التفعيل الإجباري للراية g. // بدل كل شرطة قصيرة بنقطتين متعامدين alert( '12-34-56'.replace( /-/g, ":" ) ) // 12:34:56 يمكن استخدام محارف خاصة في الوسيط الثاني كونه النص البديل. 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; } الرمز ما يفعله ضمن النص replacment &$ يمثل نص التطابق `$ يمثل النص الواقع قبل نص التطابق. '$ يمثل النص الواقع بعد نص التطابق. n$ يمثل التطابق ذا الرقم n من مجموعة التطابق (الموجود ضمن قوسي تجميع"()" ) وسنتعرف لاحقًا عليها في فصل: المجموعات الملتقطة. ‎$<name>‎ يمثل التطابق ذا الاسم name من مجموعة التطابق (الموجود ضمن قوسي تجميع"()" )، وسنتعرف لاحقًا ععليها في فصل: المجموعات الملتقطة. $$ يمثل المحرف $ إليك مثالًا: let str = "John Smith"; // swap first and last name alert(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John يمكن أن نمرر دالةً ضمن الوسيط الثاني، إذا كانت الحالة تتطلب ذلك. وستُستدعى هذه الدالة عند كل تطابق، وستصبح القيمة التي تُعيدها بمثابة النص البديل، أما شكل الدالة فهو: func(match, p1, p2, ..., pn, offset, input, groups) حيث: match: التطابق. p1, p2, ..., pn: محتويات المجموعات الملتقطة، إن وجدت. offset: موقع التطابق. input: النص الأصلي. groups: كائن يضم المجموعات المُسمّاة. إذا لم توجد أقواس ضمن التعبير النمطي فسيكون لدينا ثلاثة وسطاء فقط (func(str, offset, input. وسنعرض بعض الأمثلة: تحويل التطابقات إلى أحرف كبيرة: let str = "html and css"; let result = str.replace(/html|css/gi, str => str.toUpperCase()); alert(result); // HTML and CSS استبدال كل تطابق بموقعه في النص: alert("Ho-Ho-ho".replace(/ho/gi, (match, offset) => offset)); // 0-3-6 في المثال التالي، ستجد قوسين مفتوحين في التعبير النمطي وبالتالي ستقبل الدالة خمسة وسطاء، الأول للتطابق بأكمله، ثم محتوى القوسين، وبعدهما (لم يستخدما في مثالنا) موقع التطابق والنص الأصلي: let str = "John Smith"; let result = str.replace(/(\w+) (\w+)/, (match, name, surname) => `${surname}, ${name}`); alert(result); // Smith, John يفضل استخدام التفكيك destruction عند وجود مجموعات عدة: let str = "John Smith"; let result = str.replace(/(\w+) (\w+)/, (...match) => `${match[2]}, ${match[1]}`); alert(result); // Smith, John عندما نستخدم المجموعات المسماة، فسيكون الكائن groups مع المجموعات دائمًا في الموقع الأخير، وبالتالي سنحصل عليها بالشكل التالي: let str = "John Smith"; let result = str.replace(/(?<name>\w+) (?<surname>\w+)/, (...match) => { let groups = match.pop(); return `${groups.surname}, ${groups.name}`; }); alert(result); // Smith, John سيتيح لنا استخدام دالة عند استبدال النصوص قدرةً كبيرةً، لأنها ستزودنا بكل المعلومات عن التطابق، ولها القدرة على الوصول إلى المتغيرات الخارجية، وتنفيذ أي شيء نريده. التابع (str.replaceAll(str|regexp, str|func وله وظيفة التابع str.replace نفسها، مع وجود اختلافين رئيسيين: سيستبدل كل التطابقات الموجودة إذا كان وسيطه الأول نصًا، بينما يستبدل replace التطابق الأول فقط. يعمل تمامًا مثل التابع replace إذا كان وسيطه الأول تعبيرًا نمطيًا والراية g مفعلةً، ويعطي خطأً إذا لم تكن كذلك. ويستخدم بشكل رئيسي عندما نريد استبدال جميع التطابقات، وإليك مثالًا: // استبدل كل الشرطات بنقطتين عموديتين alert('12-34-56'.replaceAll("-", ":")) // 12:34:56 التابع (regexp.exec(str يعيد هذا التابع تطابقًا مع نمط إذا وجده ضمن النص، وعلى خلاف التوابع السابقة سيُستدعى من قبل كائن تعبير نمطي regexp وليس من قبل نص str، ويسلك سلوكًا مختلفًا عند تفعيل الراية g أو عدم تفعيلها، فإذا لم تكن هذه الراية مفعلةً فسيعيد التطابق الأول فقط، تمامًا مثل التابع (str.match(regexp، ولن يقدم هذا السلوك أي جديد، ولكن مع وجود الراية g: سيعيد التطابق الأول، ويخزن الموقع الذي يلي التطابق مباشرةً ضمن الخاصية regexp.lastIndex. عندما يُستدعى مجددًا سيبدأ البحث انطلاقًا من الموقع المُخزّّن ضمن الخاصية regexp.lastIndex معيدًا التطابق التالي، وسيخزن الموقع الذي يليه مباشرةً ضمن الخاصية regexp.lastIndex محدّثًا قيمتها. وهكذا يستمر العمل. إذا لم يجد تطابقات فسيعيد القيمة null، ويسند القيمة 0 إلى الخاصية regexp.lastIndex. سيعيد الاستدعاء المتكرر لهذا التابع كل التطابقات كما شرحنا في الخطوات السابقة، بينما قبل وجود هذا التابع، كان لا بدّ من استخدام الحلقات للحصول على التطابقات جميعها: let str = 'More about JavaScript at https://javascript.info'; let regexp = /javascript/ig; let result; while (result = regexp.exec(str)) { alert( `Found ${result[0]} at position ${result.index}` ); // Found JavaScript at position 11, then // Found javascript at position 33 } سيعمل الأسلوب المتبع في المثال السابق أيضًا، على الرغم من أنّ استخدام التابع str.matchAll سيناسب المتصفحات الحديثة أكثر. يمكن استخدام التابع (regexp.exec(str للبحث انطلاقًا من موقع محدد بضبط قيمة الخاصية regexp.lastIndex يدويًا. وإليك مثالًا: let str = 'Hello, world!'; let regexp = /\w+/g; //lastIndex يتجاهل المحرك قيمة الخاصية "g" دون الراية regexp.lastIndex = 5; // البحث انطلاقًا من الموقع 5 alert( regexp.exec(str) ); // world يفرض وجود الراية y البحث في الموقع المحدد ضمن الخاصية regexp.lastIndex تمامًا، وليس بعده. لنستبدل الراية y بالراية g في المثال السابق، وسنلاحظ عدم وجود تطابقات: let str = 'Hello, world!'; let regexp = /\w+/y; regexp.lastIndex = 5; // search exactly at position 5 alert( regexp.exec(str) ); // null يناسب هذا الأمر الحالات التي نحتاج فيها إلى قراءة شيء ما من نص باستخدام التعابير النمطية انطلاقًا من موقع محدد تمامًا. التابع (regexp.test(str يتأكد هذا التابع من وجود تطابق، ويعيد إحدى القيمتين true/false، وإليك مثالًا: let str = "I love JavaScript"; // ينفذ الاختباران التاليان العمل نفسه alert( /love/i.test(str) ); // true alert( str.search(/love/i) != -1 ); // true مثال مع جواب سلبي: let str = "Bla-bla-bla"; alert( /love/i.test(str) ); // false alert( str.search(/love/i) != -1 ); // false في الحالة التي نفعل فيها الراية g، سيبحث التابع عن الخاصية regexp.lastIndex ويحدّث قيمتها، تمامًا مثل التابع regexp.exec، لذلك يمكن استخدامه للبحث في موقع محدد: let regexp = /love/gi; let str = "I love JavaScript"; // يبدأ البحث من الموقع 10 regexp.lastIndex = 10; alert( regexp.test(str) ); // false (لا تطابق) لاحظ أنه قد يخفق الاختبار المستمر لتعبير نمطي عام على نصوص مختلفة، لأن التابع regexp.exec يستدعي قيمًا متقدمةً للخاصية regexp.lastIndex، وبالتالي قد يبدأ البحث في نص آخر ابتداءً من موقع مختلف عن الصفر. لاحظ في هذا المثال كيف سنختبر النص ذاته مرتين متتاليتين، وسيخفق الاختبار الثاني: let regexp = /javascript/g; // (regexp just created: regexp.lastIndex=0) alert( regexp.test("javascript") ); // true (regexp.lastIndex=10 now) alert( regexp.test("javascript") ); // false للالتفاف على هذه المشكلة، يمكننا ضبط قيمة الخاصية regexp.lastIndexعلى الصفر قبل البدء بكل بحث، أو استخدام توابع النصوص، مثل .../str.match/search، بدلًا من توابع التعابير النمطية، فهي لا تستخدم الخاصية lastIndex. ترجمة -وبتصرف- للفصل Methods of RegExp and string من سلسلة The Modern JavaScript Tutorial. اقرأ أيضًا المقال السابق: فهم التعقب التراجعي الكارثي في التعابير النمطية RegEx مطابقة عدة مجموعات نمطية في التعابير النمطية RegEx المحددات الكمية وأنماط استخدامها في التعابير النمطية المجموعات والمجالات في التعابير النمطية
  23. يمكن ألّا تنفق شيئًا عند نشر موقع الويب الخاص بك أو يمكن أن تتخطى الميزانية المحددة، ولهذا يمكن أن تتساءل كم سيُكلفك بناء موقع ويب كامل؟ وكيف ستجني ما أنفقته؟ سنستعرض في هذا المقال عملية تطوير موقع ويب بأكمله وحساب التكلفة المادية المتوقعة لكل خطوة، فيمكن ألّا يكون دخولك عالم الويب رخيصًا كما تعتقد. قبل الشروع في قراءة هذا المقال عليك أن تطلع على الفرق بين صفحة الويب وخادم الويب وغيرها من المصطلحات، كما عليك أن تكون على دراية بمفهوم أسماء النطاقات. البرمجيات سنتعرف في الفقرات القادمة على بعض البرمجيات الأساسية التي تحتاجها لتطوير موقع ويب والتكلفة المادية لها. محررات النصوص من المرجح أنك تملك محرر نصوص مثل المفكرة Notepad في ويندوز أو جي-إدت Gedit في لينوكس أو محرر النصوص TextEdit في ماك أو إس. لكن استخدام محرر نصوص يلوّن الشيفرات ويتحقق من صحتها قواعديًا ويساعدك في تنظيمها سيريحك ويسهِّل تطوير المواقع. يمكنك الحصول على الكثير من محررات النصوص مجانًا مثل: Atom. Brackets. Bluefish. TextWrangler. Eclipse. Netbeans. Visual Studio Code. كما يمكنك اختبار Sublime Text المدة التي تشاء لكنه سيظهر لك رسائل تشجعك على شراءه بينما يكلفك PhpStorm ما بين 20 إلى 200 دولار وفقًا للخطة التي تحتاجها. يحصل المطورون الأفراد أو مطوري المشاريع مفتوحة المصدر على Visual Studio Express مجانًا. وعادة ما تحصل على فترة تجريب مجانية للمحررات المدفوعة. ننصحك كبداية أن تجرب عدة محررات لتقرر ما يناسبك منها. كما ننصحك باستخدام محرر بسيط إن كنت ستكتب ملفات HTML وCSS وجافاسكربت بسيطة. لا يعكس ثمن المحرر جودته بالضرورة، عليك أن تجرب هذا المحرر وتقرر بنفسك إن كان يلبي احتياجاتك. يعدّ محررًا Sublime Text رخيص الثمن لكنه يأتي مع الكثير من الإضافات المجانية التي توسّع قدراته كثيرًا. محررات الصور من المرجح أن يزوّدك نظام التشغيل الذي تستخدمه بمحرر أو مستعرض صور بسيط مثل Paint في ويندوز وبرنامج Eye of Gnome في أوبونتو وبرنامج Preview في ماك. وبالطبع فهي برمجيات محدودة نسبيًا وسرعان ما تحتاج إلى محررات صور أكثر قوة لإضافة الطبقات والتأثيرات والمجموعات. يمكن أن تكون هذه المحررات مجانية مثل GIMP أو بتكلفة معقولة أقل من 100 دولار مثل PaintShop Pro أو بتكلفة عالية نسبيًا مثل أدوبي فوتوشوب Adobe Photoshop. اختر أيًا من تلك المحررات فهي تقدم وظائف متشابهة. وبالرغم من أنّ بعضها يشمل الكثير من الميزات، لكنك لن تستخدمها كلها. اطلع على الأدوات التي يستخدمها المطورون الآخرون إن كنت ستتبادل المشاريع معهم في مرحلة ما. إذ يمكن لجميع المحررات تصدير المشاريع المنجزة على شكل ملفات بتنسيقات معيارية لكنها تخزّن المشاريع التي لا تزال تحت التطوير بتنسيقات خاصة. تتمتع معظم الصور على الإنترنت بحقوق نشر، لذا عليك التحقق من رخصة استخدام الصورة قبل استخدامها. تزوّدك بعض المواقع مثل Pixabay بصور تحمل الرخصة CC0 لذا يمكنك استخدامها وتعديلها ونشرها بشكلها المعدّل لأغراض تجارية. محررات الوسائط إن أردت إضافة مقاطع فيديو أو مقاطع صوتية إلى موقعك، يمكنك تضمين خدمات ويب موجودة مثل يوتيوب YouTube أو ديلي موشن Dailymotion أو فيميو Vimeo أو تضمين مقاطع فيديو خاصة بك (تحقق من تكلفة عرض الحزمة التي سترد لاحقًا في المقال). يمكنك استخدام برامج مجانية للعمل مع المقاطع الصوتية (مثل Audacity وWavosaur) أو مدفوعة بتكاليف يمكن أن تصل لمئات من الدولارات (مثل Sony Sound Forge وAdobe Audition). وكذلك الأمر مع محررات الفيديو إذ يمكنك استخدام المحررات مجانية مثل PiTiVi وOpenShot لنظام التشغيل لينوكس وبرنامج iMovie لنظام التشغيل ماك أو إس أو يمكنك استخدام محررات معتدلة التكلفة أقل من 100 دولار مثل Adobe Premiere Elements أو بتكلفة تصل إلى مئات الدولارات (مثل Adobe Premiere Pro وAvid Media Composer وFinal Cut Pro. وغالبًا ما يغطي محرر الفيديو الذي يأتي مع كاميرتك الرقمية كل احتياجاتك. أدوات نشر المواقع ستحتاج إلى وسيلة لرفع ملفات موقعك من القرص الصلب على حاسوبك إلى خادم الويب، لذلك تساعد بعض أدوات النشر مثل S)FTP client) أو RSync أو Git/GitHub في إنجاز الأمر. يحتوي كل نظام تشغيل على برنامج عميل S)FTP) كجزء من مدير الملفات مثل Windows Explorer في ويندوز وNautilus وهو مدير ملفات شائع في أنظمة التشغيل لينوكس وMac Finder في ماك أو إس. يختار المطورون عادة برامج S)FTP) مخصصة لاستعراض المجلدات الموجودة على الحاسوب أو الخادم بشكل متجاور وتخزين كلمات مرور الخادم. هناك العديد من الخيارات الموثوقة والمجانية إن أردت أن تثبّت برنامج عميل S)FTP) مثل FileZilla لكل المنصات وWinSCP لنظام التشغيل ويندوز وCyberduck لكل من ويندوز وماك وغيرها الكثير. إنّ بروتوكول FTP غير آمن بطبيعته لذلك تأكد من استخدام SFTP وهي النسخة الآمنة المشفّرة من FTP التي تتعامل معها معظم مزودات الخدمة هذه الأيام افتراضيًا. يمكنك بالطبع استخدام تقنيات آمنة أخرى مثل Rsync مع SSH. المتصفحات إما أن يكون لديك بالفعل متصفح أو يمكنك تحميل أي متصفح مجاني مثل فايرفوكس أو كروم. الولوج إلى ويب سنتعرف الآن على التجهيزات والخدمات الأساسية التي تحتاجها لدخول ويب. حاسوب ومودم يتطلب بناء ونشر موقع ويب إلى حاسوب بتكلفة تختلف بشدة وفقًا لميزانيك ومكان إقامتك. فإن أردت نشر موقع بسيط ستحتاج إلى حاسوب بسيط قادر على تشغيل محرر ومتصفح ويب وبالتالي ستكون تكلفته قليلة عند هذا المستوى. لكن إن أردت إنتاج تصاميم أكثر تعقيدًا لموقعك تضم صورًا مؤثرة أو أن تنتج مقاطع فيديو أو مقاطع صوتية فستحتاج إلى حاسوب أفضل. تحتاج أيضًا إلى رفع الملفات إلى خادم بعيد لذلك لا بدّ من وجود مودم Modem. يمكن لمزود خدمة الإنترنت ISP أن يمنحك اتصالًا بالإنترنت مقابل بضعة دولارات شهريًا ولكن يختلف الميزانية وفقًا لمكان إقامتك. الولوج إلى مزود خدمة انترنت تأكد من أنك تستخدم حزمة اتصال (أو حيز نطاق تراسلي) bandwidth كافي: يمكن أن يكون الولوج إلى مزود الخدمة عبر حزمة اتصال منخفضة ملائمًا لدعم موقع ويب بسيط يضم صورًا بأحجام معقولة ونصوصًا وبعض ملفات التنسيق CSS وبعض ملفات جافاسكريبت، وسيكلفك ذلك بضع عشرات من الدولارات شهريًا بما في ذلك أجرة المودم. ستحتاج في المقابل إلى حزمة اتصال عريضة مثل DSL أو خدمة الكابل أو الولوج عبر الألياف الضوئية (فايبر) إن أردت موقعًا أكبر يضم مئات الملفات، أو إن أردت تزويد متابعيك بملفات فيديو أو صوت بأحجام عالية. يمكن ألا يكلفك الأمر أكثر من كلفة الحزمة المنخفضة ويمكن أن تصل التكاليف إلى مئات الدولارات شهريًا لأغراض أكثر احترافية. استضافة موقع ويب نناقش في الفقرات القادمة ما تحتاجه من خدمات لرفع موقع على ويب وتكلفة هذه الخدمات. مفهوم عرض حزمة الاستهلاك تتعلق الكلفة التي تتقاضاها مزودات الخدمة لاستضافة موقعك بعرض الحزمة التي يستهلكها الموقع. يعتمد الأمر على عدد الأشخاص الذين يزورون موقعك وعدد روبوتات ويب التي تدخل إلى موقعك لتوثيقه خلال فترة زمنية معينة، بالإضافة إلى المساحة التخزينية التي تستهلكها ملفاتك. لهذا السبب يخزن الأشخاص مقاطع الفيديو الخاصة بهم ضمن خوادم تقدم خدمات مخصصة لهذا الأمر مثل يوتيوب وديلي موشن وفيميو. يمكن أن يقدم لك مزود الخدمة عرضًا يسمح بدخول عدة آلاف من المستخدمين يوميًا وبمقدار تبادل بيانات (عرض حزمة استهلاك) معقول، ولكن يجدر بك الانتباه إلى أن ما ذكرناه سيُفسَّر بصورة مختلفة من مزود خدمة استضافة إلى آخر. وكقاعدة أساسية توقع أن تكلفك استضافة موثوقة لاستخدام شخصي ما بين 10 إلى 50 دولار شهريًا. أسماء النطاقات لا بد من شراء اسم نطاق خاص بك من خلال مزود خاص (شركة مُسجِّلة Registart أو مسجِّل)، ويمكن أن يكون مزود خدمة الاستضافة هو أيضًا مُسجّلًا (أي الشركة تقدم خدمة حجز النطاقات والاستضافة). سيكلّفك تسجيل اسم نطاق عادةً ما بين 5-15 دولار سنويًا، وتختلف هذه الكلفة للأسباب التالية: التزامات محلية: اختيارك لأسماء نطاقات عليا تحمل اسم دولة (مثل uk.) أكثر تكلفة وتختلف من دولة لأخرى. الخدمات المرتبطة باسم النطاق: تزودك بعض الشركات المسجِّلة بخدمات مثل الحماية من الإزعاجات عن طريق حجب عنوانك البريدي وعنوان بريدك الإلكتروني خلف عناوينهم الخاصة. فلن يستسطع أحد الوصول إلى عنوانك البريد إلى عن طريق الشركة المسجلّة بينما تحجب بريدك الإلكتروني وفق آلية التقنيع التي يعتمدها المُسجِّل. استضافة موقعك بنفسك أو باستخدام خدمات الاستضافة المدفوعة بإمكانك نشر موقعك بنفسك خطوة خطوة كأن تجهز قاعدة بيانات (عند الحاجة) ونظام إدارة المحتوى CMS مثل (ووردبريس Wordpress أو دوت كلير Dotclear أو spip وغيرها) وترفع قوالب المحتويات الجاهزة أو قوالبك الخاصة. كما يمكنك استخدام بيئة التشغيل الخاصة بمزود الاستضافة مقابل 10-50 دولار شهريًا، أو أن تشترك مباشرة بمزود استضافة مخصص له نظام إدارة محتوى جاهز مثل ووردبريس Wordpress أو تمبلر Tumblr أو بلوغر Blogger). لن يكلف هذا الأخير أي شيء حرفيًا، لكنك لن تكون قادرًا على التحكم الكامل بالقوالب وغيرها من الخيارات. الاستضافة المجانية مقابل الاستضافة المدفوعة يمكن أن يخطر في ببالك أنه لم عليك أن تدفع مقابل خدمة استضافة بالرغم من وجود العديد من عروض الاستضافة المجانية؟ إليك بعض المميزات للاسضافات المدفوعة: لديك حرية أكبر عندما تدفع. سيكون موقعك ملكك، وبإمكانك نقله بسلاسة من مزود خدمة إلى آخر. يمكن أن يضيف مزودي الخدمة المجانية إعلانات إلى محتوى موقعك دون أن تتحكم بذلك. يمزج البعض بين المقاربتين السابقتين، إذ يستضيفون مثلًا المدونة الرئيسية على مزود استضافة مدفوعة وباسم نطاق مستقل وخاص بالكامل، بينما يرفعون المحتوى الأقل أهمية إلى مزود استضافة مجانية. تصميم مواقع ويب والاستضافة الاحترافية عن طريق شركات خاصة إن أردت موقع ويب احترافي فيمكن أن ترغب بتوكيل المهمة لوكالة خاصة وبالتالي ستتغير التكلفة بناء على عوامل عدة مثل: هل الموقع بسيط مكون من عدة صفحات نصية؟ أم أنه أكثر تعقيدًا ويتكون من ألف صفحة مثلًا؟ هل تريد تحديث محتواه بانتظام؟ أو سيكون موقع ويب ساكن. هل ينبغي ربط الموقع بمنظومة المعلومات الخاصة بشركتك لجمع محتوى معين (مثل البيانات الداخلية)؟ هل تريد بعض الميزات الجديدة البرّاقة التي تمثل الموضة الحالية؟ حاليًا يطلب العملاء مواقع من صفحة واحدة ذات مظهر مركب. هل ترغب أن تتولى الوكالة أمر مشاكل المستخدمين أو حل مشاكل تتعلق بتجربة المستخدم UX؟ كأن تضع لك استراتيجية لتشجيع المستخدمين أو تصميم تجربة لاختيار حل من بين عدة خيارات. فيما يتعلق بالاستضافة ستتغير التكلفة بحسب عدة عوامل منها: هل تريد خوادم احتياطية في حال توقف الخادم الأساسي عن العمل؟ هل تكفي وثوقية أداء 95% أم أنك تحتاج إلى 99% وخدمة مستمرة على مدار الساعة؟ هل تريد خادمًا مخصصًا Dedicated Server عال المواصفات فائق التجاوب أم يكفيك خادم مشترك أبطأ؟ اعتمادًا على إجاباتك على كل سؤال سيكلفك الموقع من بضع آلاف وحتى مئات آلاف الدولارات. اطلعنا في هذا المقال على التكلفة المادية لبناء موقع ويب في كل خطوة من خطوات بنائه حتى نشره، وحان الوقت لتبدأ تصميم مواقع ويب وإعداد بيئة العمل المناسبة لك. ترجمة -وبتصرف- للمقال How much does it cost to do something on the Web. اقرأ أيضًا مفهوم الروابط التشعبية في مواقع الويب ما هو عنوان URL في الويب؟ ما هي الأدوات المستخدمة في بناء مواقع ويب؟ ما هي أدوات مطوري الويب المدمجة في المتصفحات؟
  24. يمكنك تنزيل معظم البرامج التي تحتاجها لتطوير صفحات ومواقع الويب مجانًا وسنزوّدك بعدة روابط خلال هذا المقال. عمومًا ستحتاج إلى أدوات التطوير لكي: تنشئ أو تحرر صفحة ويب. رفع الملفات إلى خادم ويب. استعراض موقع ويب. تحتوي معظم أنظمة التشغيل على محرر نصي ومتصفح ويب يمكن استخدامهما لعرض مواقع الويب. وبالتالي لن تحتاج سوى برامج لنقل الملفات إلى خادم ويب. إذًا، سنتعلم في هذا المقال عن المكونات البرمجية التي تحتاجها إن أردت تحرير أو رفع أو عرض موقع ويب والتي تساعدك في عملك أثناء تطوير مواقع الويب. ننصحك قبل الشروع في قراءة المقال أن تطلع على مقال الفرق بين صفحات الويب ومواقع الويب وخوادم الويب ومحركات البحث. إنشاء وتحرير صفحات الويب تحتاج إلى محرر نصي لتتمكن من تحرير أو إنشاء صفحات الويب، تساعدك محررات النصوص على تعديل الملفات النصية غير المنسّقة إذ تسمح لك بعض أنواع محررات الملفات مثل المحررات النصية الغنية Rich Text Format واختصارًا RTF، بإضافة تنسيقات إلى الخطوط المستخدمة كتثخين الخط أو وضع سطر تحت الكلمات، ولكن بالرغم من ذلك لا تعد محررات النصوص تلك ملائمة لكتابة صفحات الويب. لهذا عليك التفكير قليلًا قبل أن تقرر ما المحرر الذي ستستخدمه لأنك ستعمل عليه كثيرًا أثناء بناء موقع الويب. تأتي معظم أنظمة التشغيل المخصصة للحواسب المكتبية مع محرر نصوص بسيط وسهل الاستخدام لكنه يفتقر إلى بعض الميزات المفيدة عند كتابة شيفرات صفحات الويب. لكن إن أردت شيئًا أكثر أناقة، فستجد الكثير من الأدوات التي توفرها شركات خارجية. تأتي محررات النصوص التي تقدمها الشركات مع ميزات إضافية كتلوين العبارات القواعدية والإكمال التلقائي للشيفرة البرمجية وإخفاء أو إظهار مقاطع محددة، والبحث في الشيفرة. إليك قائمة مختصرة ببعض المحررات: 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; } نظام التشغيل المحرر المدمج مع نظام التشغيل محررات يؤمنها طرف ثالث ويندوز Notepad Notepad++, Visual Studio Code, Web Storm, Brackets ShiftEdit, Sublime Text ماك أو إس TextEdit TextWrangler, Visual Studio Code, Brackets ShiftEdit, Sublime Text لينوكس Vi (All Unix) GEdit (Gnome) Kate (KDE) LeafPad (Xfce) Emacs, Vim, Visual Studio Code, Brackets ShiftEdit, Sublime Text كروم أو إس ShiftEdit إليك لقطة شاشة لأحد محررات النصوص المتقدمة: إليك أيضًا لقطة شاشة لمحرر نصوص على الويب: رفع الملفات إلى ويب عليك أن ترفع صفحات موقعك إلى خادم ويب عندما يكتمل بناؤه ويصبح جاهزًا لاتاحته للناس. يمكنك شراء مساحة تخزين من أي مزود خدمة تختاره والذي سيرسل لك بدوره -عند إكمال عملية الشراء- بريدًا إلكترونيًا يضم معلومات الوصول إلى مساحة التخزين الخاصة بك على شكل عنوان SFTP URL (عنوان يستخدم برتوكول FTP الآمن)، بالإضافة إلى اسم المستخدم وكلمة المرور وغيرها من المعلومات اللازمة للاتصال بخادم الويب. تذكر أنّ بروتوكول SFTP أصبح قديم الطراز وبدأت أنظمة رفع ملفات جديدة باكتساب شعبية مثل RSync وGit/GitHub. تُعد خطوة رفع الملفات إلى خادم الويب خطوة مهمة جدًا من خطوات بناء الموقع، إليك قائمة مختصرة لبعض البرامج المجانية التي تعمل من ناحية العميل لرفع الملفات: نظام التشغيل برمجيات FTP ويندوز WinSCP Moba Xterm (FileZilla (All OS لينوكس (Nautilus/Files (Gnome) Dolphin (KDE ماك أو إس Cyberduck كروم أو إس (ShiftEdit (All OS تصفح مواقع ويب لا بد من وجود متصفح ويب لاستعراض المواقع وستجد الكثير من الخيارات التي تلبي احتياجاتك. لكن عندما تطور موقع ويب لا بدّ من اختباره على أحد المتصفحات الرئيسية التالية لتتأكد أن موقعك سيعمل عند معظم المستخدمين: موزيلا فايرفوكس. جوجل كروم. مايكروسوفت انترنت أكسبلورر أو مايكروسوفت إيدج. آبل سفاري. فإن كنت تستهدف مجموعة محددة (منصة تقنية أو بلد محدد)، لا بدّ أن تختبر موقعك على متصفحات أخرى مثل أوبرا وKonqueror أو UC Browser. تتعقد عملية اختبار المواقع لأن بعض المتصفحات لن تعمل إلا على أنظمة تشغيل محددة. فلن يعمل آبل سفاري سوى على أنظمة تشغيل آبل أي أو إس وماك أو إس ولن يعمل إنترنت إكسبلورر سوى على ويندوز. في حالات كهذه من الأفضل استخدام خدمات مثل Browsershots أو Browserstack. إذ سيعرضُ لك موقع Browsershots لقطات شاشة لموقعك كما سيبدو على عدة متصفحات، بينما يمنحك Browserstack إمكانية الوصول الكاملة عن بعد إلى محاكيات افتراضية Virtual Machines تساعدك على تجربة موقعك على أكثر البيئات شيوعًا. يمكنك أيضًا إعداد محاكي افتراضي خاص بك، لكن الأمر سيتطلب الأمر خبرات إضافية (إن قررت المضي بهذا الخيار، تزوّدك مايكروسوفت ببعض الأدوات التي تساعدك بما فيها محاكي افتراضي جاهز للاستخدام). اختبر موقعك بشتى الوسائل على أجهزة حقيقية وخاصة أجهزة الهواتف المحمولة الحقيقية، فالمحاكيات هي تكنولوجيا جديدة لا زالت قيد التطوير لذلك فهي أقل وثوقية من محاكيات أجهزة سطح المكتب. وطالما أن أجهزة الهاتف المحمولة غالية الثمن، ننصحك أن تلق نظرة على Open Device Lab initiative. يمكنك أيضًا مشاركة الأجهزة إن أردت اختبار موقعك على منصات عدة دون أن تنفق الكثير من المال. ترجمة -وبتصرف- للمقال What software do I need to build a website. اقرأ أيضًا ما هو عنوان URL في الويب؟ ما التكلفة المادية الكاملة لبناء موقع ويب؟ ما هي محررات النصوص المستعملة في تطوير مواقع الويب؟ ما هي أدوات مطوري الويب المدمجة في المتصفحات؟
  25. قد تبدو بعض التعابير النمطية regular expressions بسيطةً لكن قد يستغرق تنفيذها وقتًا طويلًا، وقد يسبب توقف محرك JavaScript عن الاستجابة، وسيواجه المطورون عاجلًا أم آجلًا هذا السلوك، ومن أعراضه توقف استجابة محرك تعبير نمطي يعمل جيدًا في بعض الأحيان، عندما يبحث ضمن نص معين مستهلكًا موارد المعالج 100%، حيث سيقترح المتصفح في حالة مثل هذه إيقاف تنفيذ السكربت، وإعادة تحميل الصفحة، وليس جيدًا بالطبع أن يُوقف سكربت JavaScript يعمل في الواجهة الخلفية استجابة عملية من عمليات الخادم، فلا بد إذًا من إلقاء نظرة على ذلك. مشكلة انتظار انتهاء التعبير النمطي لنفترض وجود نص نريد أن نتحقق من كونه يتألف من كلمات +w\ يفصل بينها فراغات اختيارية ?s\، حيث ستكون إحدى الطرق الواضحة إنشاء تعبير نمطي يبحث عن كلمة يليها فراغ اختياري ?w+\s\، وأخيرًا نضيف المحدد الكمي * لتكرار العملية، ويقود هذا التعبير إلى استخدام التعبير $*(?w+\s\)^ الذي يبحث عن كلمة على الأقل بالمواصفات السابقة، بحيث يبدأ البحث من بداية النص ^ وينتهي بنهايته $. let regexp = /^(\w+\s?)*$/; alert( regexp.test("A good string") ); // true ناجح alert( regexp.test("Bad characters: $@#") ); // false فاشل يبدو أنّ التعبير سيعمل والنتيجة صحيحة، لكنه في نصوص معينة سيستغرق وقتًا طويلًا حتى تتوقف استجابة محرك JavaScript، وتُستهلك موارد المعالج 100%. قد لا تلاحظ شيئًا إن نفّذت المثال التالي، لأن محرك JavaScript سيتوقف عن الاستجابة، وسيتوقف المتصفح عن التجاوب مع الأحداث، وستتوقف واجهة المستخدم عن العمل (تتيح معظم المتصفحات ميزة التمرير فقط)، وسيقترح المتصفح بعد فترة إعادة تحميل الصفحة، فكن على حذر. let regexp = /^(\w+\s?)*$/; let str = "An input string that takes a long time or even makes this regexp hang!"; // سيأخذ بعض الوقت alert( regexp.test(str) ); وعلينا القول -حتى نكون منصفين- بأن بعض محركات التعابير النمطية تتعامل مع هذا النوع من البحث بفعالية، فالمحرك "V8" وابتداءً من النسخة 8.8 قادر على ذلك، فلن تتوقف استجابة المتصفح 88 Chrome في حالات مثل هذه، بينما ستتوقف استجابة متصفح Firefox. السؤال الذي طرح نفسه، ما المشكلة؟ لماذا تتوقف استجابة التعبير النمطي؟ لتوضيح ذلك دعونا نبسّط المثال السابق بإزالة الفراغات ?S\، وبالتالي سيصبح التعبير النمطي على الشكل $*(?w+\s\)^، ولتوضيح الأمر أكثر دعونا نستبدل الصنف d\ بالصنف w\، وستتوقف مع ذلك استجابة التعبير الجديد أيضًا، فمثلًا: let regexp = /^(\d+)*$/; let str = "012345678901234567890123456789z"; // انتبه، سيأخذ بعض الوقت alert( regexp.test(str) ); ما المشكلة في هذا التعبير النمطي؟ قد يلاحظ القارئ أنّ التعبير *(+d\) غريب بعض الشيء، فوجود المحدد الكمي * يبدو مبالغًا فيه، فإن أردنا عددًا يمكن استخدام d\، ومع ذلك يبدو التعبير الجديد المبسط عمليًا أكثر، لكن سبب بطئه أيضًا لم يتغير، لهذا علينا دراسته بالتفصيل للوقوف على المشكلة، فما الذي يحدث أثناء البحث عن النمط $*(+d\)^ ضمن النص 123456789z، واختُصر قليلًا للوضوح، ولماذا يستغرق الأمر وقتًا؟ إليك ما يفعله المحرك: أولًا، يحاول المحرك بدايةً البحث عن محتوى الأقواس، وهي الأعداد +d\، وطالما أنّ + محدد كمي جشع greedy افتراضيًا فسيضم كل الأرقام في النص. \d+....... (123456789)z عند ضم الأرقام جميعها يعدُّ المحرك أن البحث عن +d\ قد أنجز، وأن النتيجة هي 123456789، ثم ينتقل بعد ذلك إلى تطبيق المحدد الكمي *، لكن الأرقام في النص قد استهلكت جميعها، فلن يقدم مرتكز البداية ^ أي شيء، ثم يبحث المحرك عن آخر محارف النمط $، ولن يجده لأنّ المحرف الباقي من النص هو z: X \d+........$ (123456789)z ثانيًا، وطالما أنّ التطابق غير موجود فسينقص المُكمِّم + عدد المحارف واحدًا ويعيد البحث، لذلك ستكون نتيجة +d\ كل الأرقام عدا الأخير 12345678: \d+....... (12345678)9z ثالثًا، يحاول المحرك الآن البحث في الموقع التالي بعد 12345678، وعندها يمكن تطبيق المكمِّم *، وسيعطي النمط *(+d\) تطابقًا جديدًا وهو 9. \d+.......\d+ (12345678)(9)z ثم يحاول المحرك من جديد إيجاد آخر محرف من النمط $ فلن يجده، بل سيجد المحرف الباقي من النص، وهو z: X \d+.......\d+ (12345678)(9)z رابعًا، لن يحصل المحرك على التطابق المطلوب؛ وسيستمر في العودة والتعقب مخفضًا عدد التكرارات وهذا ما يسمى بعملية التعقب التراجعي Backtracking أو التراجع والمطابقة ببساطة، وتجري عملية التعقب التراجعي عادةً بالشكل التالي: يقلل آخر محدد كمي جشع عدد التكرارات حتى يصل إلى الحد الأدنى، ثم يأتي دور المحدد الكمي الجشع الذي يسبقه في إنقاص عدد التكرارات وهكذا، إلى أن يتقصى المحرك كل الحالات الممكنة، وإليك بعض الأمثلة عن هذه الحالات: العدد الأول مؤلف من 7 أرقام، ثم عدد برقمين: X \d+......\d+ (1234567)(89)z العدد الأول من 7 أرقام، ثم عددين كل منهما مكون من رقم واحد: X \d+......\d+\d+ (1234567)(8)(9)z العدد الأول من 6 أرقام، والثاني من ثلاثة: X \d+.......\d+ (123456)(789)z العدد الأول من 6 أرقام، يليه عددان آخران: X \d+.....\d+ \d+ (123456)(78)(9)z ويوجد عدد كبير من الاحتمالات التي نفصل فيها سلسلةً من الأرقام 123456789 إلى أعداد، ولنكون أكثر دقة توجد ‎2<sup>n</sup>-1 طريقة، حيث n هو طول سلسلة الأرقام، ففي حالة 9 أرقام -كما في حالتنا- لدينا 511 احتمال، أما في حالة 20 رقمًا فلدينا 1048575 احتمال، وبالتالي سيسبب مرور المحرك بهذه الحالات التأخير. العودة إلى الكلمات والنصوص يحدث الأمر ذاته كما في مثالنا الأول، عندما بحثنا عن كلمات باستخدام النمط $*(?w+\s\)^ ضمن النص التالي: An input that hangs!‎ والسبب طبعًا أن الكلمة +w\ قد تُمثَّل بعدد كبير من الحالات: (input) (inpu)(t) (inp)(u)(t) (in)(p)(ut) ... قد يكون عدم وجود التطابق واضحًا، لأن النص ينتهي بإشارة تعجب، لكن ما يتوقعه التعبير النمطي هو محرف كلمة w\ أو فراغ s\ في النهاية، وهذا ما لا يعرفه المحرك، إذ سيبحث عن كل الحالات التي يحتمل أن تطابق فيها النمط *(?w+\s\) كل محارف النص، بما في ذلك الحالات التي تضم الفراغ *(w+\s\) أو التي لا تضمها *(+w\)، لأن النمط ?s\ اختياري، وسيستغرق وقتًا طويلًا نظرًا لوجود عدد كبير من الحالات التي سيستكشفها المحرك، فما العمل؟ هل علينا تفعيل البحث الكسول lazy mode؟ لن يساعدنا ذلك لسوء الحظ، ستتوقف الاستجابة أيضًا إذا استبدلنا النمط ?+w\ بالنمط +w\، وسيتغير ترتيب الحالات التي سيبحث فيها المحرك فقط، وليس عددها. تتجنب بعض محركات التعبير النمطي المرور على كل الحالات من خلال بعض الاختبارات، أو استخدام وسائل أتمتة محدودة، أو قد تجعل العملية أكثر سرعةً، ومع ذلك لا تتبع معظم المتصفحات هذه الأساليب، كما أنها لا تساعد دومًا. ما هو الحل؟ توجد مقاربتان لحل المشكلة، الأولى تخفيض عدد الحالات الممكنة، فمثلًا لنجعل المساحة الفارغة إجباريةً، بجعل النمط بالشكل التالي $*w+\s)*\w\)^، أي سنبحث عن أي عدد من الكلمات التي يفصل بينها فراغ، عدا الكلمة الأخيرة فستكون اختيارية w\*، سينتهي البحث سواء وجدت أم لا، انظر إلى التعبير التالي المكافئ للسابق (يحصل على التطابقات نفسها) ويعمل جيدًا: let regexp = /^(\w+\s)*\w*$/; let str = "An input string that takes a long time or even makes this regex hang!"; alert( regexp.test(str) ); // false لماذا اختفت المشكلة؟ لأن الفراغ بين الكلمات أصبح إجباريًا، فلو حذفنا الفراغ في التعبير السابق فسيقود إلى عدد أكبر من حالات +w\ ضمن الكلمة ذاتها، إذ يمكن الحصول على الكلمة input من تكرارين +w\ بالشكل التالي: \w+ \w+ (inp)(ut) لكن النمط الجديد مختلف، فالكلمة متبوعة بفراغ حتمًا *(w+\s\)، وبالتالي لن نحصل على الكلمة من خلال تكرارين للنمط w+\s\، وبهذا لن يهدر المزيد من الوقت في البحث عن كل الحالات الممكنة للحصول على كلمة. منع التعقب التراجعي في التعابير النمطية لن تساعدنا إعادة كتابة النمط دائمًا، إذ كانت العملية سهلةً وواضحةً في المثال السابق، لكنها عادةً ليست كذلك، كما ستقود إعادة كتابة النمط إلى أنماط أكثر تعقيدًا، وهذا أمر سيء، فالتعابير النمطية معقدة بطبيعتها، لحسن الحظ توجد مقاربة بديلة تقتضي منع التعقب التراجعي backtracking للمحدد الكمي، فأصل المشكلة هو تجربة المحرًك للكثير من الحالات الخاطئة -من وجهة نظرنا طبعًا-، فمن الواضح أنّ تعقب + في النمط $*(+d\) سيسبب مشكلةً، ولن يتغير شيء إن بدّلنا النمط +d+\d\ بالنمط +d\: \d+........ (123456789)! \d+...\d+.... (1234)(56789)! وقد نرغب في مثالنا الأصلي $*(?w+\s\)^ بمنع تعقب +w\، لأنها من المفترض أن تبحث عن كلمة كاملة بأكبر طول ممكن، ولا حاجة لتخفيض عدد التكرارات، أو فصلها إلى كلمتين +w+\w\ وهكذا. تدعم محركات التعابير النمطية الحديثة المحددات الكمية الاستحواذية possessive quantifiers عن طريق إضافة الإشارة + بعد المحدد الكمي، أي نضع ++d\ بدلًا من +d\، وذلك لمنعه من الوقوع في فخ التعقب التراجعي، فالمحددات الكمية الاستحواذية أبسط من النظامية، حيث تطابق ما تستطيع من المحارف دون الوقوع في التعقب التراجعي، وسيكون البحث آنذاك أبسط. كما يوجد ما يُسمى "المجموعات الذرية الملتقطة" atomic capturing groups، وهو وسيلة لمنع التعقب التراجعي ضمن الأقواس، والخبر السيئ هو أنها غير مدعومة في JavaScript، لكن يمكن تقليدها باستخدام شرط التحقق مما يلي المطابقة lookahead transform. البحث عن الخلاص لقد وصلنا إلى موضوع متقدم فعلًا، إذ نريد منع المحددات الكمية -مثل +- من التعقب التراجعي، لأن تعقب بعض الأمور غير منطقي على الإطلاق. إنّ النمط الذي يأخذ أكبر عدد ممكن من تكرارات w\ دون تعقب تراجعي هو 1\((+w\)=?)، وبالطبع يمكن اختيار أي نمط بدل w\، وقد يبدو النمط غريبًا، لكنه في الواقع تحويل بسيط، لنصفه: سيبحث نمط البحث قُدُمًا =? عن أطول كلمة +w\ ابتداءً من الموقع الحالي. لن يتذكر المحرك محتوى ما بين القوسين المسبوق بالمحارف =?، لذلك وضعنا +w\ ضمن أقواس، ثم سيتذكر المحرك محتوى القوسين التاليين. ثم نشير إلى الأقواس الخارجية بالرقم 1. سيتقدم البحث إلى الأمام وعند وجود كلمة +w\ فسيحددها بالرقم 1\، وبكذا سنكون قد صممنا محددًا كميًا استحواذيًا من المحدد الكمي +، حيث يلتقط الكلمة +w\ كاملةً فقط، وليس جزءًا منها، فيمكن مثلًا الحصول على الكلمة Java من الكلمة JavaScript، وترك الكلمة Script لتتطابق مع بقية النمط، وإليك موازنةً بين نمطين: alert( "JavaScript".match(/\w+Script/)); // JavaScript alert( "JavaScript".match(/(?=(\w+))\1Script/)); // null في الحالة الأولى: سنحصل على الكلمة كاملةً، لكن المحدد الكمي سيتعقب بقية النمط متراجعًا محرفًا محرفًا، محاولًا إيجاد بقية النمط، ثم سينجح أخيرًا، عندما يتطابق النمط +w\ الكلمة Java. في الحالة الثانية: سيجري البحث قُدمًا وسيجد الكلمة JavaScript كاملةً، وسيحددها بالرقم 1، وبالتالي لا طريقة بعد ذلك لإيجاد الكلمة Script. يمكن استخدام تعابير نمطية أكثر تعقيدًا من w\ ضمن 1\((+w\)=?) عندما نريد منع التعقب التراجعي للمحدد الكمي +. لنكتب مثالنا الأول باستخدام التحقق مما يلي التطابق لمنع التعقب التراجعي: let regexp = /^((?=(\w+))\2\s?)*$/; alert( regexp.test("A good string") ); // true let str = "An input string that takes a long time or even makes this regex hang!"; alert( regexp.test(str) ); // false, يعمل وبسرعة وضعنا 2\ بدلًا من الرقم 1\ لوجود أقواس خارجية إضافية، كما يمكننا تسمية الأقواس أيضًا (+<word>\w>?). // ?<word>وتُسمى الأقواس كالتالي, \k<word>يشار إلى الأقواس كالتالي let regexp = /^((?=(?<word>\w+))\k<word>\s?)*$/; let str = "An input string that takes a long time or even makes this regex hang!"; alert( regexp.test(str) ); // false alert( regexp.test("A correct string") ); // true خلاصة تُسمى المشكلة التي وصفناها في هذا المقال بالتعقب التراجعي الكارثي، وغطينا طريقتين لحلها: تخفيض عدد الحالات الممكنة التي تتطابق مع نمط إلى الحد الأدنى. منع التعقب التراجعي. ترجمة -وبتصرف- للفصل Catastrophic backtracking من سلسلة The Modern JavaScript Tutorial. اقرأ أيضًا أساسيات البحث باستخدام التعابير النمطية في جافاسكربت المجموعات والمجالات في التعابير النمطية التعابير النمطية (regexp/PCRE) في PHP
×
×
  • أضف...