يوضّح لك هذا الدرس التطبيقي حول الترميز كيفية تنفيذ تجربة بحث متينة باستخدام Workbox. يحتوي التطبيق التجريبي الذي يستخدمه على مربّع بحث يستدعي نقطة نهاية خادم ويعيد توجيه المستخدم إلى صفحة HTML أساسية.
القياس
قبل إضافة تحسينات، من الأفضل دائمًا تحليل الحالة الحالية للتطبيق أولاً.
- انقر على Remix to Edit (إنشاء ريمكس لتعديل المحتوى) ليصبح المشروع قابلاً للتعديل.
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة .
في علامة التبويب الجديدة التي تم فتحها للتو، تحقّق من سلوك الموقع الإلكتروني عند عدم الاتصال بالإنترنت:
- اضغط على Ctrl + Shift + J (أو Command + Option + J على نظام التشغيل Mac) لفتح DevTools.
- انقر على علامة التبويب الشبكة.
- افتح "أدوات مطوّري البرامج في Chrome" واختَر لوحة "الشبكة".
- في القائمة المنسدلة "تقييد السرعة"، اختَر بلا إنترنت.
- في التطبيق التجريبي، أدخِل طلب بحث، ثم انقر على الزر بحث.
تظهر صفحة الخطأ العادية للمتصفّح:
تقديم ردّ احتياطي
يحتوي عامل الخدمة على الرمز البرمجي لإضافة الصفحة بلا إنترنت إلى قائمة التخزين المؤقت المُسبَق، حتى يمكن تخزينها مؤقتًا في أي وقت عند حدوث الحدث install
لعامل الخدمة.
عادةً ما تحتاج إلى توجيه Workbox لإضافة هذا الملف إلى قائمة التخزين المؤقت المُسبَق في وقت الإنشاء، وذلك من خلال دمج المكتبة مع أداة الإنشاء التي تختارها (مثل webpack أو gulp).
لتسهيل الأمر عليك، سبق أن أجرينا ذلك نيابةً عنك. تؤدي التعليمة البرمجية التالية في public/sw.js
إلى تنفيذ ذلك:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
بعد ذلك، أضِف رمزًا لاستخدام الصفحة بلا إنترنت كاستجابة احتياطية:
- لعرض المصدر، اضغط على عرض المصدر.
- أضِف الرمز التالي إلى أسفل
public/sw.js
:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
تؤدي التعليمة البرمجية ما يلي:
- لتحديد استراتيجية الشبكة فقط التلقائية التي سيتم تطبيقها على جميع الطلبات
- تُعلن عن معالج أخطاء عام، من خلال استدعاء
workbox.routing.setCatchHandler()
لإدارة الطلبات التي تعذّر إكمالها. عندما تكون الطلبات متعلّقة بالمستندات، سيتم عرض صفحة HTML احتياطية بلا إنترنت.
لاختبار هذه الوظيفة:
- ارجع إلى علامة التبويب الأخرى التي تعمل على تشغيل تطبيقك.
- اضبط القائمة المنسدلة Throttling (تقييد السرعة) مرة أخرى على Online (متصل بالإنترنت).
- اضغط على زر رجوع في Chrome للانتقال مرة أخرى إلى صفحة البحث.
- تأكَّد من أنّ مربّع الاختيار إيقاف ذاكرة التخزين المؤقت في "أدوات مطوّري البرامج" غير مفعَّل.
- اضغط مع الاستمرار على زر إعادة التحميل في Chrome واختَر إفراغ ذاكرة التخزين المؤقت وإعادة التحميل من جديد لضمان تحديث الخدمة العاملة.
- اضبط القائمة المنسدلة تقييد السرعة مرة أخرى على بلا إنترنت.
- أدخِل طلب بحث، ثم انقر على الزر بحث مرة أخرى.
يتم عرض صفحة HTML الاحتياطية:
طلب إذن إرسال الإشعارات
للتبسيط، تحتوي صفحة وضع عدم الاتّصال بالإنترنت على الرابط views/index_offline.html
على الرمز البرمجي لطلب أذونات إرسال الإشعارات في مجموعة نصوص برمجية في أسفل الصفحة:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
تؤدي التعليمة البرمجية ما يلي:
- عندما ينقر المستخدم على الاشتراك في الإشعارات، يتمّ استدعاء الدالة
requestNotificationPermission()
التي تستدعيNotification.requestPermission()
لعرض طلب الإذن التلقائي للمتصفّح. يتم حلّ الوعد بالإذن الذي يختاره المستخدم، والذي يمكن أن يكونgranted
أوdenied
أوdefault
. - تمرير الإذن الذي تم حلّه إلى
showOfflineText()
لعرض النص المناسب للمستخدم
الاحتفاظ بطلبات البحث بلا إنترنت وإعادة المحاولة عند استعادة الاتصال بالإنترنت
بعد ذلك، يمكنك تنفيذ مزامنة Workbox في الخلفية للحفاظ على طلبات البحث بلا إنترنت، حتى يمكن إعادة تجربتها عندما يرصد المتصفّح استعادة الاتصال بالإنترنت.
- افتح
public/sw.js
للتعديل. - أضِف الرمز التالي في نهاية الملف:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
تؤدي التعليمة البرمجية ما يلي:
- يحتوي
workbox.backgroundSync.Plugin
على منطق لإضافة الطلبات غير الناجحة إلى قائمة انتظار حتى يمكن إعادة محاولة إجرائها لاحقًا. سيتم الاحتفاظ بهذه الطلبات في IndexedDB. - يشير الرمز
maxRetentionTime
إلى المدة التي يمكن خلالها إعادة محاولة إرسال طلب. في هذه الحالة، اخترنا 60 دقيقة (بعدها سيتم تجاهل السجلّ). onSync
هو الجزء الأكثر أهمية في هذا الرمز. سيتم استدعاء دالة ردّ الاتصال هذه عند استعادة الاتصال حتى يتم استرداد الطلبات التي في "قائمة الانتظار" ثم جلبها من الشبكة.- تتم إضافة استجابة الشبكة إلى ذاكرة التخزين المؤقت
offline-search-responses
، مع إلحاق مَعلمة طلب البحث¬ification=true
، حتى يمكن اختيار إدخال ذاكرة التخزين المؤقت هذا عندما ينقر المستخدم على الإشعار.
لدمج المزامنة في الخلفية مع خدمتك، حدِّد استراتيجية NetworkOnly للطلبات المرسَلة إلى عنوان URL للبحث (/search_action
) وأرسِل القيمة bgSyncPlugin
المحدّدة سابقًا. أضِف الرمز التالي إلى أسفل public/sw.js
:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
يطلب هذا من Workbox الانتقال دائمًا إلى الشبكة، وعند تعذُّر الطلبات، استخدام منطق المزامنة في الخلفية.
بعد ذلك، أضِف الرمز البرمجي التالي إلى أسفل public/sw.js
لتحديد استراتيجية تخزين مؤقت للطلبات الواردة من الإشعارات. استخدِم استراتيجية CacheFirst لكي يتم عرضها من ذاكرة التخزين المؤقت.
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
أخيرًا، أضِف الرمز لعرض الإشعارات:
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
اختبار الميزة
- ارجع إلى علامة التبويب الأخرى التي تعمل على تشغيل تطبيقك.
- اضبط القائمة المنسدلة Throttling (تقييد السرعة) مرة أخرى على Online (متصل بالإنترنت).
- اضغط على زر رجوع في Chrome للانتقال مرة أخرى إلى صفحة البحث.
- اضغط مع الاستمرار على زر إعادة التحميل في Chrome واختَر إفراغ ذاكرة التخزين المؤقت وإعادة التحميل من جديد لضمان تحديث الخدمة العاملة.
- اضبط القائمة المنسدلة تقييد السرعة مرة أخرى على بلا إنترنت.
- أدخِل طلب بحث، ثم انقر على الزر بحث مرة أخرى.
- انقر على الاشتراك في الإشعارات.
- عندما يسألك Chrome ما إذا كنت تريد منح التطبيق الإذن بإرسال الإشعارات، انقر على سماح.
- أدخِل طلب بحث آخر وانقر على الزر بحث مرة أخرى.
- اضبط القائمة المنسدلة Throttling (تقييد السرعة) مرة أخرى على Online (متصل بالإنترنت).
بعد استعادة الاتصال، سيظهر إشعار:
الخاتمة
يوفّر Workbox العديد من الميزات المدمجة لجعل تطبيقات الويب التقدّمية أكثر مرونة وتفاعلية. في هذا الدليل التعليمي حول الرموز البرمجية، تعرّفت على كيفية تنفيذ Background Sync API من خلال Workbox، لضمان عدم فقدان طلبات بحث المستخدمين بلا اتصال بالإنترنت، وإمكانية إعادة المحاولة بعد استعادة الاتصال. العرض التقديمي هو تطبيق بحث بسيط، ولكن يمكنك استخدام عملية تنفيذ مشابهة لسيناريوهات وحالات استخدام أكثر تعقيدًا، بما في ذلك تطبيقات المحادثة ونشر الرسائل على شبكة اجتماعية وما إلى ذلك.