قد تحتاج بعض المواقع الإلكترونية إلى التواصل مع مشغّل الخدمات بدون الحاجة إلى على اطلاع بالنتيجة. وإليك بعض الأمثلة:
- ترسل الصفحة إلى عامل الخدمة قائمة بعناوين URL إلى الجلب المسبق، وبالتالي عندما ينقر المستخدم على تكون الموارد الفرعية للمستند أو الصفحة متوفرة بالفعل في ذاكرة التخزين المؤقت، مما يجعل التنقل بشكل أسرع بكثير.
- تطلب الصفحة من عامل الخدمة استرداد مجموعة من أهم المقالات وتخزينها مؤقتًا لعرضها في ذاكرة التخزين المؤقت. متوفر لأغراض عدم الاتصال بالإنترنت.
ويفيد تفويض هذه الأنواع من المهام غير المُهمّة إلى عامل الخدمة بإتاحة سلسلة التعليمات الرئيسية للتعامل بشكل أفضل مع المهام الأكثر إلحاحًا مثل الاستجابة لتفاعلات المستخدم.
سوف نستكشف في هذا الدليل كيفية تطبيق أسلوب تواصل أحادي الاتجاه من الصفحة إلى مشغّل الخدمة باستخدام واجهات برمجة التطبيقات (API) القياسية للمتصفح ومكتبة Workbox. سنسمي هذه الأنواع من للتخزين المؤقت الضروري لحالات الاستخدام.
حالة الإنتاج
نفّذ موقع 1-800-Flowers.com عملية التخزين المؤقت الضروري (الجلب المسبق) مع مشغّلي الخدمة عبر
postMessage()
لجلب
أهم العناصر في صفحات الفئات لتسريع عملية التنقل اللاحقة إلى صفحات تفاصيل المنتج.
وتستخدم هذه الطريقة نهجًا مختلطًا لتحديد العناصر التي سيتم جلبها مسبقًا:
- في وقت تحميل الصفحة، تطلب من عامل الخدمة استرداد بيانات JSON لأهم 9 عناصر. لإضافة كائنات الاستجابة الناتجة إلى ذاكرة التخزين المؤقت.
- بالنسبة إلى العناصر المتبقية، سيستمع المستخدم إلى
mouseover
. ، بحيث عندما يحرّك المستخدم المؤشر فوق أحد العناصر، فيمكنه بدء عملية جلب للمورد عند "الطلب".
تستخدم Cache API لتخزين JSON الردود:
عندما ينقر المستخدم على عنصر ما، يمكن اختيار بيانات JSON المرتبطة به من ذاكرة التخزين المؤقت، دون الحاجة إلى الانتقال إلى الشبكة، مما يجعل التنقل أسرع.
استخدام Workbox
يوفر Workbox طريقة سهلة لإرسال الرسائل إلى
مشغّل الخدمات، عبر حزمة workbox-window
، مجموعة من الوحدات
المُعَدة للعمل في سياق النافذة. تُعد تكملة لحزم Workbox الأخرى
التي يتم تشغيلها في مشغّل الخدمات.
لتوصيل الصفحة بمشغّل الخدمات، عليك أولاً الحصول على مرجع كائن Workbox مشغّل الخدمات المسجَّل:
const wb = new Workbox('/sw.js');
wb.register();
ثم يمكنك إرسال الرسالة بشكل مباشر وبياني، دون المعاناة من الحصول على التسجيل، أو التحقق من التفعيل، أو التفكير في واجهة برمجة تطبيقات الاتصالات الأساسية:
wb.messageSW({"type": "PREFETCH", "payload": {"urls": ["/data1.json", "data2.json"]}}); });
ينفِّذ عامل الخدمة معالج message
من أجل
استمع إلى هذه الرسائل. ويمكنها اختياريًا عرض إجابة، على الرغم من أنه في مثل هذه الحالات،
غير ضروري:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PREFETCH') {
// do something
}
});
استخدام واجهات برمجة التطبيقات للمتصفّح
إذا لم تكن مكتبة Workbox كافية لتلبية احتياجاتك، إليك كيفية تنفيذ ميزة النافذة للخدمة. على اتصال العامل، باستخدام واجهات برمجة تطبيقات المتصفح.
postMessage API لإنشاء آلية اتصال باتجاه واحد من الصفحة إلى مشغّل الخدمات.
تطلب الصفحة
postMessage()
في صفحة
واجهة مشغّل الخدمات:
navigator.serviceWorker.controller.postMessage({
type: 'MSG_ID',
payload: 'some data to perform the task',
});
ينفِّذ عامل الخدمة معالج message
من أجل
استمع إلى هذه الرسائل.
self.addEventListener('message', (event) => {
if (event.data && event.data.type === MSG_ID) {
// do something
}
});
السمة {type : 'MSG_ID'}
غير مطلوبة بشكل كامل، وهي إحدى الطرق التي تتيح للصفحة
إرسال أنواع مختلفة من التعليمات إلى مشغّل الخدمات (أي "الجلب المسبق" مقابل "محو البيانات"
التخزين"). وقد يتفرع عامل الخدمة إلى مسارات تنفيذ مختلفة بناءً على هذه العلامة.
إذا تمت العملية بنجاح، فسيتمكن المستخدم من الحصول على الفوائد منها، ولكن إذا لم يكن الأمر كذلك، فلن يغير تدفق المستخدم الرئيسي. على سبيل المثال، عندما يحاول 1-800-Flowers.com التخزين المؤقت، لن تحتاج الصفحة إلى معرفة ما إذا كان مشغّل الخدمة قد نجح أم لا. إذا كان الأمر كذلك، فسيتمتع المستخدم بتنقل أسرع. وإذا لم يتم حلّ المشكلة، تحتاج الصفحة إلى الانتقال إلى الصفحة الجديدة. سيستغرق الأمر وقتًا أطول قليلاً.
مثال بسيط للجلب المسبق
الجلب المسبق هو أحد أكثر التطبيقات شيوعًا لاستخدام التخزين المؤقت الضروري، وهو ما يعني استرجاع الموارد الخاصة بعنوان URL معين، قبل أن ينتقل المستخدم إليه، وذلك لتسريع عملية التنقل.
هناك طرق مختلفة لتنفيذ الجلب المُسبَق في المواقع الإلكترونية:
- استخدام علامات الجلب المسبق للروابط في الصفحات: يتم الاحتفاظ بالموارد في
ذاكرة التخزين المؤقت في المتصفح لمدة خمس دقائق، وبعدها يتم تطبيق قواعد
Cache-Control
العادية للمورد تطبيقها. - استكمال الأسلوب السابق باستراتيجية التخزين المؤقت في وقت التشغيل في الخدمة Worker لإطالة عمر الجلب المُسبَق موردًا يتجاوز هذا الحد.
بالنسبة إلى سيناريوهات الجلب المسبق البسيطة نسبيًا، مثل الجلب المسبق للمستندات، أو أصول محددة (JS، CSS، إلخ)، فهذه الأساليب هي أفضل أسلوب.
إذا كان الأمر يتطلب منطقًا إضافيًا، على سبيل المثال، تحليل مورد الجلب المسبق (ملف أو صفحة JSON) في لجلب عناوين URL الداخلية الخاصة به، فمن الأفضل تفويض هذه المهمة بالكامل إلى مشغّل الخدمات.
ويحصل تفويض عامل الخدمة على هذه الأنواع من العمليات على المزايا التالية:
- تفريغ الأحمال الثقيلة الناتجة عن الجلب والمعالجة بعد الجلب (والذي سيتم طرحه لاحقًا) إلى سلسلة محادثات ثانوية. يؤدي هذا الإجراء إلى تفريغ سلسلة التعليمات الرئيسية لمعالجتها مهام مثل الاستجابة لتفاعلات المستخدم.
- السماح لعدة عملاء (مثل علامات التبويب) بإعادة استخدام وظيفة شائعة، وحتى استدعاء بشكل متزامن بدون حظر سلسلة التعليمات الرئيسية.
الجلب المسبق لصفحات تفاصيل المنتجات
أول استخدام postMessage()
في
واجهة مشغّل الخدمات وتمرير صفيف من عناوين URL إلى ذاكرة التخزين المؤقت:
navigator.serviceWorker.controller.postMessage({
type: 'PREFETCH',
payload: {
urls: [
'www.exmaple.com/apis/data_1.json',
'www.exmaple.com/apis/data_2.json',
],
},
});
في مشغّل الخدمات، يمكنك تنفيذ معالِج message
من أجل
اعتراض الرسائل المُرسَلة من أي علامة تبويب نشطة ومعالجتها:
addEventListener('message', (event) => {
let data = event.data;
if (data && data.type === 'PREFETCH') {
let urls = data.payload.urls;
for (let i in urls) {
fetchAsync(urls[i]);
}
}
});
قدّمنا في الرمز البرمجي السابق دالة مساعدة صغيرة تُسمى fetchAsync()
لتكرارها في
مصفوفة من عناوين URL وإصدار طلب جلب لكل عنوان منها:
async function fetchAsync(url) {
// await response of fetch call
let prefetched = await fetch(url);
// (optionally) cache resources in the service worker storage
}
عند الحصول على الاستجابة، يمكنك الاعتماد على عناوين التخزين المؤقت للمورد. في كثير من الحالات
ومع ذلك، كما هو الحال في صفحات تفاصيل المنتج، لا يتم تخزين الموارد مؤقتًا (مما يعني أن لها
عنوان Cache-control
لـ no-cache
). في مثل هذه الحالات، يمكنك إلغاء هذا السلوك، عن طريق
تخزين المورد الذي تم استرجاعه في ذاكرة التخزين المؤقت لعامل الخدمات. وهذه ميزة إضافية تتمثل في السماح
عرضه في سيناريوهات بلا اتصال بالإنترنت.
بيانات أخرى غير JSON
بعد جلب بيانات JSON من نقطة نهاية الخادم، غالبًا ما تحتوي على عناوين URL أخرى تستحق الجلب المسبق، مثل صورة أو بيانات نقطة نهاية أخرى مرتبطة بهذا المستوى الأول البيانات.
لنفترض أنه في المثال الذي ذكرناه، بيانات JSON المعروضة هي معلومات تابعة لموقع تسوق البقالة:
{
"productName": "banana",
"productPic": "https://cdn.example.com/product_images/banana.jpeg",
"unitPrice": "1.99"
}
تعديل رمز fetchAsync()
لتكرار قائمة المنتجات وتخزين الصورة الرئيسية مؤقتًا
كل واحد منها:
async function fetchAsync(url, postProcess) {
// await response of fetch call
let prefetched = await fetch(url);
//(optionally) cache resource in the service worker cache
// carry out the post fetch process if supplied
if (postProcess) {
await postProcess(prefetched);
}
}
async function postProcess(prefetched) {
let productJson = await prefetched.json();
if (productJson && productJson.product_pic) {
fetchAsync(productJson.product_pic);
}
}
يمكنك إضافة بعض معالجة الاستثناءات حول هذا الرمز في حالات مثل أخطاء 404. ولكن جمال استخدام عامل خدمة للجلب المسبق هو أنه قد يفشل بدون الكثير تحدث للصفحة وسلسلة المحادثات الرئيسية. قد يكون لديك أيضًا منطق أكثر تفصيلاً في ما بعد معالجة المحتوى الذي يتم جلبه مسبقًا، ما يزيد من مرونة المحتوى وفصله عن البيانات التي يعرضها ومعالجتها. لا حدود تواجهك سوى السماء.
الخاتمة
تناولنا في هذه المقالة حالة استخدام شائعة للاتصال باتجاه واحد بين الصفحة والخدمة. عامل: التخزين المؤقت الضروري. تهدف الأمثلة التي تمت مناقشتها فقط إلى إظهار طريقة واحدة باستخدام هذا النمط ويمكن تطبيق نفس النهج على حالات استخدام أخرى كذلك، على سبيل المثال، التخزين المؤقت لأهم المقالات عند الطلب للاستهلاك بلا اتصال بالإنترنت، ووضع الإشارات المرجعية، وغير ذلك.
للتعرف على المزيد من أنماط اتصال الصفحة وعاملي الخدمات، اطلع على:
- تحديثات البث: الاتصال بالصفحة من عامل الخدمة لإبلاغه بالصفحة عن التحديثات المهمة (على سبيل المثال، يتوفر إصدار جديد من تطبيق الويب).
- التواصل المتبادل: تفويض مهمة إلى عامل خدمة (على سبيل المثال، تنزيل مكثف)، وإبقاء الصفحة على اطلاع بالتقدم.