تصور عمل عمال الخدمة



يوم جيد يا اصدقاء!

ربما سمع الكثير منكم عن مثل هذا الابتكار في نظام JavaScript البيئي مثل Service Workers ، والتي تعد عنصرًا أساسيًا لتطوير الويب الحديث. أصبح عمال الخدمة أكثر شعبية ، ويرجع ذلك في المقام الأول إلى شعبية تطبيقات الويب التقدمية (PWA).

عندما سمعت عنها لأول مرة ، سألت نفسي: "متى يجب أن نستخدم عمال الخدمة؟ في أي سيناريوهات أو سياق يمكننا استخدامها؟ "

في هذه المقالة ، سننظر في العديد من الأمثلة العملية لاستخدام عمال الخدمة ، والتي أجرؤ على أملها لاحقًا ، ستجعل المستخدمين سعداء.

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

ما هو عامل الخدمة؟


Cersis Worker هو برنامج نصي يتم تشغيله بواسطة متصفح في عملية الخلفية. تذكر أن عامل الخدمة مستقل تمامًا عن الصفحة التي يتفاعل معها أو التي يخدمها (للعرض).

في الأساس ، عامل الخدمة هو خادم وكيل بين تطبيق ويب ومتصفح وشبكة.

يسمح عمال الخدمة لتطبيقات الويب بالعمل مثل التطبيقات الأصلية.

بعض الحقائق عن عمال الخدمة


  • عمال الخدمة ليس لديهم وصول مباشر إلى DOM. للقيام بذلك ، يستخدمون آلية الاستجابة للطلبات من خلال واجهة postMessages.
  • يتم إلغاء عمال الخدمة (بالقوة) بالقوة عندما لا يكون قيد الاستخدام. هذا يعني أنها مدفوعة بالحدث.
  • يفترض عمال الخدمة استخدام الوعود (الوعود).
  • نظرًا للإمكانيات الرائعة ، لا يمكن استخدام عمال الخدمة إلا عبر HTTPS. على خادم محلي ، يمكنك الاستغناء عن HTTPS.

كيف يعمل عمال الخدمة؟ نظرة سريعة


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

ولكن من الأفضل رؤيتها مرة واحدة ، لذلك هذه صورة توضح عمل عامل الخدمة:



دورة حياة عامل الخدمة


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

بعد ذلك ، ينتقل المتصفح الذي بدأ تثبيت عامل الخدمة إلى الخلفية:



حالات الاستخدام الشائعة


الآن بعد أن عرفنا كيف يعمل عمال الخدمة ، حان الوقت للحديث عن مكان استخدامهم.

التخزين المؤقت


كما ذكر أعلاه ، يمكن استخدام عمال الخدمة للتخزين المؤقت. وهنا بعض الأمثلة:

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

دفع الويب


يسمح Web push للتطبيقات بإرسال إعلامات الدفع وعرض المحتوى المستلم استجابة لهذه الإخطارات.

  • دفع وتحديث المحتوى - تريد مشاركة (تسليم واستلام) المحتوى المتاح.
  • الدفع والمحتوى - لا تريد العمل فقط مع النص ، ولكن أيضًا مع أنواع أخرى من المعلومات التي تثري رسائلك.
  • دفع مشبع - تريد عرض الصور وعملية التمهيد وأشياء أخرى تحسن الرسالة التي تريد توصيلها.
  • Push and client - تريد إظهار الإخطارات حسب حالة التطبيق.

حالات استخدام أكثر تعقيدًا


تحليلات API


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

موازن التحميل


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

أوصي بشدة بزيارة ServiceWorke.rs لإلقاء نظرة أكثر تعمقًا على عمال الخدمة.

نمارس المهارات


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

تسجيل عامل الخدمة


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

//   
if('serviceWorker' in navigator){
    console.log('- ')
    //     
    //      "load"
    window.addEventListener('load', () => {
        //  -
        navigator.serviceWorker
        .register('/service-worker.js')
        .then(registration => {
            //   
            console.log(`-  , scope: ${registration.scope}`) // scope -  ,     -
        })
    })
    .catch(error => {
        //  
        console.log(`    : ${error}`)
    })
}

يمكنك التحقق من عمل عامل الخدمة بالانتقال إلى: Chrome: // Inspection / # service-worker.



أيضا ، يمكن الحصول على معلومات حول حالة عامل الخدمة في أدوات المطور: التطبيق -> عمال الخدمة.



ماذا بعد؟


الآن نحن بحاجة إلى تخزين جميع الملفات. يمكننا تحديد الملفات للتخزين المؤقت. إليك ما يبدو عليه:

//  
const CACHE_NAME = 'example.com-v1'
//    
const cacheAssets = ['index.html', 'about.html', 'js/main.js']
//    "install"
self.addEventListener('install', e => {
    console.log('- ')
    e.waitUntil(
        caches
            .open(CACHE_NAME)
            .then(cache => {
                console.log('  -:  ')
                cache.addAll(cacheAssets)
            })
            .then(() => {
                self.skipWaiting()
            })
    )
})

إليك ما يحدث هنا:

  1. نحدد اسم ذاكرة التخزين المؤقت (example.com-v1).
  2. نختار الملفات للتخزين المؤقت. للقيام بذلك ، قم بإنشاء صفيف.
  3. داخل معالج أحداث "التثبيت" ، نطلب من المتصفح الانتظار حتى اكتمال الوعد ، ثم فتح ذاكرة التخزين المؤقت ، والتي سيتم حفظها تحت اسم "example.com-v1".
  4. أخيرًا ، أضف الملفات المحددة إلى ذاكرة التخزين المؤقت.

حذف ذاكرة التخزين المؤقت غير المستخدمة


بعد ذلك ، نحتاج إلى إزالة إصدارات ذاكرة التخزين المؤقت القديمة:

//    "activate"
self.addEventListener('activate', e => {
    console.log('- ')
    e.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames.map(cache => {
                    if(cache !== CACHE_NAME){
                        console.log('   ')
                        return caches.delete(cache)
                    }
                })
            )
        })
    )
})

تلقي الرد


لا يُعد أي مما سبق أمرًا منطقيًا إذا لم يكن لدينا طريقة للحصول على محتوى مخبأ.

يمكن الحصول عليها باستخدام معالج حدث الجلب:

//    "fetch"
self.addEventListener('fetch', e => {
    e.respondWith(
        fetch(e.request)
            .then(res => {
                const copyCache = res.clone()
                caches.open(CACHE_NAME).then(cache => {
                    cache.put(e.request, copyCache)
                })
                return res
            })
            .catch(error => caches.match(e.request).then(res => res))
    )
})

يمكن الاطلاع على جميع التعليمات البرمجية هنا .

شكرآ لك على أهتمامك.

All Articles