تسجيل مشغّلي الخدمات

أفضل الممارسات لتحديد توقيت تسجيل مشغّل الخدمات

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

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

النص النموذجي للتسجيل الشائعة

إذا كنت قد قرأت عن عمال الخدمات، فمن المحتمل أن تكون قد صادفت نصًا نموذجيًا مشابهًا إلى حد كبير لما يلي:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
}

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

إذًا، هل هناك أي فروقات طفيفة حول navigator.serviceWorker.register؟ هل هناك أي أفضل الممارسات التي يجب اتباعها؟ ومن غير المستغرب (نظرًا إلى أن هذه المقالة لا تنتهي هنا)، فإن الإجابة عن كليهما هي "نعم!"

زيارة المستخدم الأولى

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

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

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

من غير المرجّح أن تُحدث سلسلة التعليمات في الخلفية غير النشِطة فارقًا كبيرًا. ولكن ماذا لو لم تكن سلسلة التعليمات هذه غير نشطة، ولكنها ستبدأ أيضًا في تنزيل الموارد من الشبكة؟ يجب التراجع عن أي قلق بشأن وحدة المعالجة المركزية (CPU) أو تزايد الطلب على الذاكرة حول معدل نقل البيانات المحدود المتاح للعديد من الأجهزة الجوّالة. يُعد معدل نقل البيانات ثمينًا، لذلك لا تقلل من الموارد المهمة عن طريق تنزيل موارد ثانوية في نفس الوقت.

مغزى حديثك هو أنّ تشغيل سلسلة تعليمات جديدة لمشغّلي الخدمات لتنزيل الموارد وتخزينها مؤقتًا في الخلفية يمكن أن يصبّ في مصلحة هدفك المتمثل في توفير أقصر مدة ممكنة للتفاعل مع المستخدم في المرة الأولى التي يزور فيها المستخدم موقعك.

تحسين النص النموذجي

يتمثّل الحل في التحكّم في بدء مشغّل الخدمات من خلال اختيار وقت الاتصال بالرقم navigator.serviceWorker.register(). هناك قاعدة أساسية بسيطة، وهي تأخير التسجيل إلى ما بعد إطلاق load event في window، على النحو التالي:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}

غير أنّ الوقت المناسب لبدء تسجيل مشغّل الخدمات قد يعتمد أيضًا على الإجراءات التي ينفّذها تطبيق الويب بعد تحميله مباشرةً. على سبيل المثال، يعرض تطبيق الويب Google I/O 2016 صورة متحركة قصيرة قبل الانتقال إلى الشاشة الرئيسية. اكتشف فريقنا أن بدء تسجيل عامل الخدمة أثناء تشغيل الرسوم المتحركة قد يؤدي إلى خلل في الأجهزة المحمولة منخفضة المواصفات. وبدلاً من تقديم تجربة سيئة للمستخدمين، أؤخّرنا تسجيل عامل الخدمة إلى أن يتم بعد تشغيل الرسوم المتحركة، عندما يكون من المرجّح أن يظل المتصفّح بضع ثوانٍ غير نشطة.

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

الزيارات اللاحقة

لقد ركّزنا حتى الآن على تجربة الزيارة الأولى، ولكن ما هو تأثير تأخير تسجيل موظفي الخدمات على الزيارات المتكررة إلى موقعك الإلكتروني؟ رغم أنه قد يفاجئ بعض الناس، فلن يكون هناك أي تأثير على الإطلاق.

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

لذلك، عندما يصبح هناك عامل خدمات نشط، لا يهمّ ما إذا كان يتم الاتصال بـ navigator.serviceWorker.register() أو في الواقع استخدامه على الإطلاق. ما لم يتم تغيير عنوان URL للنص البرمجي لمشغّل الخدمات، يكون navigator.serviceWorker.register() فعليًا no-op خلال الزيارات اللاحقة. عندما يتم استدعائها، لا تكون ذات صلة.

أسباب التسجيل المبكر

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

اختبار الأشياء

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

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

حركة بيانات الشبكة مع التسجيل المبكر.

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

حركة بيانات الشبكة مع تأخُّر التسجيل.

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

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

الخلاصة

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

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

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}