في عام 2015، قدمنا ميزة "مزامنة الخلفية" التي تتيح عامل الخدمة لتأجيل العمل حتى يكون لدى المستخدم إمكانية الاتصال. هذا يعني أن المستخدم يمكنه كتابة ثم اضغط على إرسال، ثم يغادر الموقع مع العلم أنه سيتم إرسال الرسالة إما الآن أو عند الاتصال.
وهي ميزة مفيدة، ولكنها تتطلب أن يكون عامل الخدمة على قيد الحياة طوال مدة جلب. هذه ليست مشكلة في فترات قصيرة من العمل مثل إرسال رسالة، ولكن إذا استغرقت المهمة حيث سيؤدي المتصفح إلى إنهاء عامل الخدمة، وإلا فقد يمثل ذلك خطرًا على خصوصية المستخدم البطارية.
لذا، ماذا لو احتجت إلى تنزيل محتوى قد يستغرق وقتًا طويلاً، مثل فيلم أو ملفات بودكاست المستويات في اللعبة. ولهذا السبب، تم استخدام ميزة جلب الخلفية.
تتوفّر ميزة الجلب في الخلفية بشكل تلقائي منذ الإصدار Chrome 74.
إليك عرض توضيحي سريع مدته دقيقتان يوضحان الحالة التقليدية للأشياء مقارنةً باستخدام ميزة الجلب في الخلفية:
جرِّب العرض التوضيحي بنفسك وتصفّح الرمز.
آلية العمل
تعمل عملية الجلب في الخلفية على النحو التالي:
- يمكنك الطلب من المتصفّح تنفيذ مجموعة من عمليات الجلب في الخلفية.
- يجلب المتصفح تلك الأشياء، ويعرض التقدم للمستخدم.
- بعد اكتمال عملية الجلب أو تعذُّر إكمالها، يفتح المتصفّح مشغّل الخدمات وينشّط حدثًا. لإخبارك بما حدث. هذا هو المكان الذي تقرر فيه ما يجب أن تفعله بالردود، إن وجد.
وإذا أغلق المستخدم صفحات على موقعك الإلكتروني بعد الخطوة 1، لا بأس في ذلك، ستستمر عملية التنزيل. لأنّ مدى وضوح عملية جلب البيانات ويسهل إلغاءها، وليس هناك أي قلق بشأن الخصوصية من منظور لمزامنة البيانات في الخلفية. لا داعي للقلق لأنّ عامل الخدمة لا يعمل بشكل متواصل. من إساءة استخدام النظام، مثل تعدين بيتكوين في الخلفية.
في بعض الأنظمة الأساسية (مثل Android)، يمكن أن يتم إغلاق المتصفح بعد الخطوة 1، المتصفّح الذي يسلّم الجلب إلى نظام التشغيل.
إذا بدأ المستخدم عملية التنزيل بلا اتصال بالإنترنت أو انقطع اتصاله بالإنترنت أثناء عملية التنزيل، يتم استخدام الخلفية سيتم إيقاف الجلب مؤقتًا واستئنافها لاحقًا.
واجهة برمجة التطبيقات
اكتشاف الميزات
وكما هو الحال مع أي ميزة جديدة، تحتاج إلى معرفة ما إذا كان المتصفّح يتيحها أم لا. بالنسبة إلى ميزة الجلب في الخلفية، بسيطة مثل:
if ('BackgroundFetchManager' in self) {
// This browser supports Background Fetch!
}
بدء استرجاع البيانات في الخلفية
تتأثر واجهة برمجة التطبيقات الرئيسية بتسجيل عامل الخدمة، لذا احرص على تسجيل مشغّل الخدمات أولاً. بعد ذلك:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.fetch('my-fetch', ['/ep-5.mp3', 'ep-5-artwork.jpg'], {
title: 'Episode 5: Interesting things.',
icons: [{
sizes: '300x300',
src: '/ep-5-icon.png',
type: 'image/png',
}],
downloadTotal: 60 * 1024 * 1024,
});
});
تستخدم backgroundFetch.fetch
ثلاث وسيطات:
المعلمات | |
---|---|
id |
string تحدّد هذه الميزة الجلب في الخلفية بشكل فريد. سيتم رفض " |
requests |
Array<Request|string>
العناصر المطلوب جلبها. يتم التعامل مع السلاسل باعتبارها عناوين URL ويتم تحويلها إلى Request عبر new Request(theString) .
يمكنك استرجاع محتوى من مصادر أخرى طالما أنّ الموارد تسمح بذلك من خلال CORS. ملاحظة: لا يدعم Chrome حاليًا الطلبات التي قد تتطلب طلبًا تمهيديًا بسياسة CORS. |
options |
كائن قد يتضمّن ما يلي: |
options.title |
string عنوان للمتصفِّح يعرضه مع مستوى التقدّم. |
options.icons |
Array<IconDefinition> يشير ذلك المصطلح إلى مصفوفة من العناصر التي تتضمّن "src" و"size" و"type". |
options.downloadTotal |
number الحجم الإجمالي لنصات الاستجابة (بعد فك ضغطها باستخدام gzip). وعلى الرغم من أنّ هذه الخطوة اختيارية، إلا أنّنا ننصحك بشدة بتقديمها. يتم استخدامها لسرد للمستخدم حجم التنزيل، وتوفير معلومات التقدم. في حال عدم تقديم فسيُخبر المتصفح المستخدم بأنّ الحجم غير معروف، وبالتالي قد يكون احتمالية إلغاء التنزيل. إذا تجاوزت عمليات تنزيل استرجاع البيانات في الخلفية الرقم الوارد هنا، سيتم إيقافها. من المهم
إذا كان حجم الملف الذي سيتم تنزيله أصغر من |
ترجع "backgroundFetch.fetch
" وعودًا يتم حلّه من خلال "BackgroundFetchRegistration
". وإلى اللقاء
بتناول تفاصيل ذلك لاحقًا. يرفض الوعد إذا اختار المستخدم إيقاف عمليات التنزيل أو رفض
المعلَمات المُقدمة غير صالحة.
يتيح لك تقديم العديد من الطلبات لجلب خلفية واحدة دمج الأشياء التي تعتبر شيء واحد للمستخدم. فعلى سبيل المثال، قد يتم تقسيم الفيلم إلى آلاف الموارد من الموارد (بشكل نموذجي مع MPEG-DASH) وتوفّر موارد إضافية مثل الصور يمكن أن ينتشر مستوى من اللعبة عبر العديد موارد جافا سكريبت والصور والصوت. ولكن بالنسبة إلى المستخدم، يتعلق الأمر فقط "بالفيلم" أو "المستوى".
الحصول على أداة استرجاع حالية للخلفية
يمكنك الحصول على عملية جلب حالية للخلفية على النحو التالي:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
...عن طريق ضبط id (المعرّف) لعملية استرجاع البيانات في الخلفية التي تريدها. يتم إرجاع مبلغ undefined
من قِبل "get
" في حال عدم توفّر
جلب نشط في الخلفية باستخدام هذا المعرّف.
يعتبر الجلب في الخلفية "نشطًا" منذ لحظة تسجيلها، إلى أن يتم ذلك بنجاح، أو فشله أو إلغائه.
يمكنك الحصول على قائمة بجميع عمليات الجلب النشطة في الخلفية باستخدام getIds
:
navigator.serviceWorker.ready.then(async (swReg) => {
const ids = await swReg.backgroundFetch.getIds();
});
عمليات تسجيل الجلب في الخلفية
يتميز BackgroundFetchRegistration
(bgFetch
في الأمثلة أعلاه) بما يلي:
أماكن إقامة | |
---|---|
id |
string معرّف عملية الاسترجاع في الخلفية: |
uploadTotal |
number عدد وحدات البايت المراد إرسالها إلى الخادم. |
uploaded |
number عدد وحدات البايت التي تم إرسالها بنجاح. |
downloadTotal |
number القيمة التي تمّ تقديمها عند تسجيل عملية الاسترجاع في الخلفية صفر. |
downloaded |
number عدد وحدات البايت التي تم استلامها بنجاح. وقد تنخفض هذه القيمة. على سبيل المثال، إذا انقطع الاتصال ولم يتمكن التنزيل إعادة تشغيل، في هذه الحالة سيعيد المتصفح تشغيل الجلب لهذا المورد من البداية. |
result |
يجب استخدام إحدى السمات التالية:
|
failureReason |
يجب استخدام إحدى السمات التالية:
|
recordsAvailable |
boolean هل يمكن الوصول إلى الطلبات أو الردود الأساسية؟ عندما يصبح هذا خطأ، لا يمكن استخدام |
الطُرق | |
abort() |
تعرض Promise<boolean> إلغاء عملية الاسترجاع في الخلفية. يتم حل الوعد الذي تم إرجاعه بشكل صحيح في حال إلغاء عملية الجلب بنجاح. |
matchAll(request, opts) |
المرتجعات Promise<Array<BackgroundFetchRecord>> الحصول على الطلبات والردود. الوسيطة هنا هي نفس ذاكرة التخزين المؤقت API. الاتصال بدون وسيطات يؤدي وعدًا بالحفاظ على جميع السجلات. انظر أدناه للحصول على مزيد من التفاصيل. |
match(request, opts) |
عرض Promise<BackgroundFetchRecord> على النحو الوارد أعلاه، ولكن تتم مطابقته مع المطابقة الأولى. |
فعاليات | |
progress |
يتم الإطلاق عندما يكون أي من uploaded أو downloaded أو result أو
تغيير في failureReason |
تتبُّع مستوى التقدّم
ويمكن إجراء ذلك من خلال حدث "progress
". تذكَّر أنّ downloadTotal
هي أي قيمة
أو 0
إذا لم يتم تقديم أي قيمة.
bgFetch.addEventListener('progress', () => {
// If we didn't provide a total, we can't provide a %.
if (!bgFetch.downloadTotal) return;
const percent = Math.round(bgFetch.downloaded / bgFetch.downloadTotal * 100);
console.log(`Download progress: ${percent}%`);
});
الحصول على الطلبات والردود
bgFetch.match('/ep-5.mp3').then(async (record) => {
if (!record) {
console.log('No record found');
return;
}
console.log(`Here's the request`, record.request);
const response = await record.responseReady;
console.log(`And here's the response`, response);
});
record
هو BackgroundFetchRecord
، ويبدو على النحو التالي:
أماكن إقامة | |
---|---|
request |
Request الطلب الذي تم تقديمه |
responseReady |
Promise<Response> الردّ الذي تم استرجاعه الرد متأخِّر عن وعود لأنّه ربما لم يتم تلقّيه بعد. الموعد النهائي سيتم رفضه في حال فشل الجلب. |
أحداث مشغّل الخدمات
فعاليات | |
---|---|
backgroundfetchsuccess |
تم استرجاع كل البيانات بنجاح. |
backgroundfetchfailure |
تعذّر استرجاع واحدة أو أكثر. |
backgroundfetchabort |
تعذّرت عملية جلب واحدة أو أكثر.
هذا مفيد حقًا فقط إذا كنت تريد إجراء تنظيف من البيانات ذات الصلة. |
backgroundfetchclick |
نقر المستخدم على واجهة مستخدم تقدّم عملية التنزيل. |
تحتوي كائنات الحدث على ما يلي:
أماكن إقامة | |
---|---|
registration |
BackgroundFetchRegistration |
الطُرق | |
updateUI({ title, icons }) |
للسماح لك بتغيير العنوان/الرموز التي ضبطتها في البداية. يعد هذا اختياريًا، لكنه يتيح لك
وتوفر المزيد من السياق إذا لزم الأمر. يمكنك إجراء ذلك *مرة* فقط خلال
backgroundfetchsuccess وbackgroundfetchfailure حدث. |
التفاعل مع النجاح/الفشل
لقد سبق لنا عرض حدث progress
، ولكن هذا الإجراء مفيد فقط عندما يكون لدى المستخدم صفحة مفتوحة
موقعك الإلكتروني. تتمثل الفائدة الرئيسية من استرجاع البيانات في الخلفية في استمرار سير الأمور بعد مغادرة المستخدم
الصفحة، أو حتى إغلاق المتصفح.
إذا اكتملت عملية استرجاع البيانات في الخلفية بنجاح، سيتلقّى عامل الخدمة
backgroundfetchsuccess
، وسيكون event.registration
هو تسجيل الاسترجاع في الخلفية.
بعد هذا الحدث، لن تتمكّن من الوصول إلى الطلبات والردود التي تم جلبها، لذا إذا أردت واحتفظ بها، وانقلها إلى مكان مثل واجهة برمجة تطبيقات ذاكرة التخزين المؤقت.
كما هو الحال مع معظم أحداث مشغّلي الخدمات، استخدِم event.waitUntil
حتى يعرف عامل الخدمة موعد الحدث.
مكتملة.
على سبيل المثال، في مشغّل الخدمات:
addEventListener('backgroundfetchsuccess', (event) => {
const bgFetch = event.registration;
event.waitUntil(async function() {
// Create/open a cache.
const cache = await caches.open('downloads');
// Get all the records.
const records = await bgFetch.matchAll();
// Copy each request/response across.
const promises = records.map(async (record) => {
const response = await record.responseReady;
await cache.put(record.request, response);
});
// Wait for the copying to complete.
await Promise.all(promises);
// Update the progress notification.
event.updateUI({ title: 'Episode 5 ready to listen!' });
}());
});
قد يرجع الإخفاق إلى خطأ 404 واحد، وهو ما ربما لم يكن مهمًا بالنسبة إليك، لذا ربما لا تزال تستحق نسخ بعض الردود إلى ذاكرة تخزين مؤقت على النحو الوارد أعلاه.
التفاعل مع النقر
واجهة المستخدم التي تعرض مستوى تقدم التنزيل والنتيجة قابلة للنقر الحدث backgroundfetchclick
في
عامل الخدمة يتيح لك التفاعل مع ذلك. كما هو موضح أعلاه، ستكون event.registration
الخلفية
وجلب التسجيل.
الشيء الشائع لفعل هذا الحدث هو فتح نافذة:
addEventListener('backgroundfetchclick', (event) => {
const bgFetch = event.registration;
if (bgFetch.result === 'success') {
clients.openWindow('/latest-podcasts');
} else {
clients.openWindow('/download-progress');
}
});
مراجع إضافية
تصحيح: هناك إصدار سابق من هذه المقالة أشارت عن طريق الخطأ إلى ميزة "جلب الخلفية" على أنّها "معيار ويب". لا تتوفّر واجهة برمجة التطبيقات حاليًا على مسار المعايير، ويمكنك الاطّلاع على المواصفات في WICG كمسودة تقرير مجموعة المنتدى.