بنية تطبيقات الويب التقدمية: أنماط مُشغِّل الخدمات (Service Worker) في JavaScript | MLOG | MLOG

4. الشبكة فقط (Network-Only)

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

مثال:

            
self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request)
  );
});

            

5. قديم أثناء إعادة التحقق (Stale-While-Revalidate)

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

مثال:

            
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        const fetchPromise = fetch(event.request).then(networkResponse => {
          caches.open('my-cache').then(cache => {
            cache.put(event.request, networkResponse.clone());
            return networkResponse;
          });
        });
        return response || fetchPromise;
      })
  );
});

            

6. التخزين المؤقت، ثم الشبكة (Cache, then Network)

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

اختيار استراتيجية التخزين المؤقت المناسبة

تعتمد استراتيجية التخزين المؤقت المثلى على المتطلبات المحددة لتطبيقك. ضع في اعتبارك عوامل مثل:

من خلال اختيار استراتيجيات التخزين المؤقت المناسبة بعناية، يمكنك تحسين أداء وتجربة مستخدم تطبيق PWA الخاص بك بشكل كبير، حتى في البيئات غير المتصلة بالإنترنت. يمكن لأدوات مثل Workbox ([https://developers.google.com/web/tools/workbox](https://developers.google.com/web/tools/workbox)) تبسيط تنفيذ هذه الاستراتيجيات.

المزامنة في الخلفية: التعامل مع التغييرات في وضع عدم الاتصال

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

تسجيل مهمة مزامنة في الخلفية

لتسجيل مهمة مزامنة في الخلفية، تحتاج إلى استخدام طريقة `register` الخاصة بـ `BackgroundSyncManager`. تأخذ هذه الطريقة اسم علامة فريد كوسيطة. يحدد اسم العلامة المهمة المحددة التي سيتم تنفيذها.

مثال:

            
self.addEventListener('sync', event => {
  if (event.tag === 'my-sync-task') {
    event.waitUntil(doSomeWork());
  }
});

            

التعامل مع حدث المزامنة (sync)

عندما يكتشف المتصفح وجود اتصال بالشبكة، فإنه يرسل حدث `sync` إلى مُشغِّل الخدمات. يمكنك الاستماع لهذا الحدث وتنفيذ الإجراءات اللازمة، مثل إرسال البيانات إلى الخادم.

مثال:

            
async function doSomeWork() {
  // Retrieve data from IndexedDB
  const data = await getDataFromIndexedDB();

  // Send data to the server
  try {
    const response = await fetch('/api/sync', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json'
      }
    });

    if (response.ok) {
      // Clear the data from IndexedDB
      await clearDataFromIndexedDB();
    } else {
      // Handle errors
      console.error('Sync failed:', response.status);
      throw new Error('Sync failed');
    }
  } catch (error) {
    // Handle network errors
    console.error('Network error:', error);
    throw error;
  }
}

            

مثال: إرسال نموذج في وضع عدم الاتصال

تخيل سيناريو يقوم فيه المستخدم بملء نموذج أثناء عدم الاتصال بالإنترنت. يمكن لمشغِّل الخدمات تخزين بيانات النموذج في IndexedDB وتسجيل مهمة مزامنة في الخلفية. عندما تصبح الشبكة متاحة، سيقوم مُشغِّل الخدمات باسترداد بيانات النموذج من IndexedDB وإرسالها إلى الخادم.

  1. يقوم المستخدم بملء النموذج والنقر على إرسال أثناء عدم الاتصال بالإنترنت.
  2. يتم تخزين بيانات النموذج في IndexedDB.
  3. يتم تسجيل مهمة مزامنة في الخلفية بعلامة فريدة (مثل، `form-submission`).
  4. عندما تكون الشبكة متاحة، يتم تشغيل حدث `sync`.
  5. يقوم مُشغِّل الخدمات باسترداد بيانات النموذج من IndexedDB وإرسالها إلى الخادم.
  6. إذا كان الإرسال ناجحًا، تتم إزالة بيانات النموذج من IndexedDB.

الإشعارات: إشراك المستخدمين بتحديثات في الوقت المناسب

تُمكّن الإشعارات تطبيق PWA الخاص بك من إرسال تحديثات ورسائل في الوقت المناسب للمستخدمين، حتى عندما لا يكون التطبيق قيد التشغيل في المتصفح. يمكن أن يؤدي هذا إلى تحسين مشاركة المستخدمين والاحتفاظ بهم بشكل كبير. تعمل واجهة برمجة التطبيقات Push API و Notifications API معًا لتقديم الإشعارات.

الاشتراك في الإشعارات

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

مثال:

            
navigator.serviceWorker.ready.then(registration => {
  registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: 'YOUR_PUBLIC_VAPID_KEY'
  })
  .then(subscription => {
    // Send subscription details to your server
    sendSubscriptionToServer(subscription);
  })
  .catch(error => {
    console.error('Failed to subscribe:', error);
  });
});

            

هام: استبدل `YOUR_PUBLIC_VAPID_KEY` بمفتاح VAPID العام الفعلي الخاص بك (Voluntary Application Server Identification). تُستخدم مفاتيح VAPID لتحديد خادم التطبيق الخاص بك وضمان إرسال الإشعارات بشكل آمن.

التعامل مع الإشعارات

عندما يتم استلام إشعار، يرسل مُشغِّل الخدمات حدث `push`. يمكنك الاستماع لهذا الحدث وعرض الإشعار للمستخدم.

مثال:

            
self.addEventListener('push', event => {
  const payload = event.data ? event.data.text() : 'No payload';

  event.waitUntil(
    self.registration.showNotification('My PWA', {
      body: payload,
      icon: 'icon.png'
    })
  );
});

            

تخصيص الإشعارات

تسمح لك واجهة برمجة التطبيقات Notifications API بتخصيص مظهر وسلوك الإشعارات. يمكنك تحديد العنوان، والنص، والأيقونة، والشارة، وخيارات أخرى.

مثال:

            
self.addEventListener('push', event => {
  const data = event.data.json();
  const title = data.title || 'My PWA';
  const options = {
    body: data.body || 'No message',
    icon: data.icon || 'icon.png',
    badge: data.badge || 'badge.png',
    vibrate: [200, 100, 200],
    data: { // Custom data that you can access when the user clicks the notification
      url: data.url || '/'
    },
    actions: [
      {action: 'explore', title: 'Explore this new world',
        icon: 'images/checkmark.png'},
      {action: 'close', title: 'Close',
        icon: 'images/xmark.png'},
    ]
  };

  event.waitUntil(self.registration.showNotification(title, options));
});


self.addEventListener('notificationclick', function(event) {
  event.notification.close();

  // Check if the user clicked on an action.
  if (event.action === 'explore') {
    clients.openWindow(event.notification.data.url);
  } else {
    // Default action: open the app.
    clients.openWindow('/');
  }
});

            

مثال: تنبيه إخباري

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

أنماط مُشغِّل الخدمات المتقدمة

1. التحليلات في وضع عدم الاتصال

تتبع سلوك المستخدم حتى عندما يكونون غير متصلين بالإنترنت عن طريق تخزين بيانات التحليلات محليًا وإرسالها إلى الخادم عندما تكون الشبكة متاحة. يمكن تحقيق ذلك باستخدام IndexedDB و Background Sync.

2. إدارة الإصدارات والتحديثات

نفذ استراتيجية قوية لإدارة الإصدارات لمشغِّل الخدمات الخاص بك لضمان حصول المستخدمين دائمًا على آخر التحديثات دون تعطيل تجربتهم. استخدم تقنيات "cache busting" لإلغاء صلاحية الموارد المخزنة مؤقتًا القديمة.

3. مُشغِّلات الخدمات المعيارية (Modular)

نظم كود مُشغِّل الخدمات الخاص بك في وحدات (modules) لتحسين قابلية الصيانة والقراءة. استخدم وحدات JavaScript (ESM) أو أداة تجميع وحدات مثل Webpack أو Rollup.

4. التخزين المؤقت الديناميكي

قم بتخزين الموارد مؤقتًا بشكل ديناميكي بناءً على تفاعلات المستخدم وأنماط الاستخدام. يمكن أن يساعد ذلك في تحسين حجم ذاكرة التخزين المؤقت وتحسين الأداء.

أفضل الممارسات لتطوير مُشغِّل الخدمات

الخاتمة

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

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

مصادر إضافية: