في عام 2015، أطلقنا ميزة "مزامنة الخلفية" التي تتيح لعامل الخدمة تأجيل العمل حتى يتوفّر للمستخدم إمكانية الاتصال. وهذا يعني أنه يمكن للمستخدم كتابة رسالة، والضغط على إرسال، وترك الموقع على علم بأنه سيتم إرسال الرسالة إما الآن أو عندما يكون لديه اتصال.
وهي ميزة مفيدة، ولكن تتطلب أن يكون عامل الخدمة نشطًا طوال مدة الجلب. لا يمثل ذلك مشكلة في أجزاء قصيرة من العمل مثل إرسال رسالة، ولكن إذا استغرقت المهمة وقتًا طويلاً، فسيقتل المتصفح عامل الخدمة، وإلا فسيعرّض المتصفح خطرًا على خصوصية المستخدم وبطاريته.
حسنًا، ماذا لو احتجت إلى تنزيل شيء قد يستغرق وقتًا طويلاً، مثل فيلم أو بودكاست أو مستويات لعبة. هذا هو الغرض من ميزة الجلب في الخلفية.
تتوفّر ميزة "الجلب في الخلفية" تلقائيًا بدءًا من الإصدار 74 من متصفّح Chrome.
هذا عرض توضيحي سريع مدته دقيقتان يوضح الحالة التقليدية للأشياء مقابل استخدام جلب الخلفية:
جرِّب الإصدار التجريبي بنفسك وتصفَّح الرمز.
آلية العمل
تعمل عملية الجلب في الخلفية على النحو التالي:
- تطلب من المتصفّح تنفيذ مجموعة من عمليات الجلب في الخلفية.
- يجلب المتصفّح هذه العناصر ويعرض مستوى التقدّم للمستخدم.
- بعد اكتمال الجلب أو تعذّر تنفيذه، يفتح المتصفّح مشغّل الخدمات وينشط حدثًا لإعلامك بما حدث. هذا هو المكان الذي تقرر فيه ما يجب فعله بالردود، إن وجدت.
إذا أغلق المستخدم صفحات من موقعك الإلكتروني بعد الخطوة 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 الحجم الإجمالي لنص الاستجابة (بعد فك ضغطه). على الرغم من أنّ هذا الإجراء اختياري، فإنّنا ننصح بشدة بتقديمه. ويتم استخدامه لإبلاغ المستخدم بحجم عملية التنزيل ولتقديم معلومات عن مستوى التقدّم. وفي حال عدم توفير هذه المعلومات، سيخبر المتصفح المستخدم بأنّ الحجم غير معروف، ما قد يزيد احتمال إلغاء المستخدم لعملية التنزيل. في حال تجاوزت عمليات تنزيل الجلب في الخلفية العدد الموضح هنا، سيتم إلغاء العملية. لا بأس على الإطلاق إذا كان حجم التنزيل أصغر من |
تعرض السمة backgroundFetch.fetch
تعهدًا يتم حلّه باستخدام BackgroundFetchRegistration
. سأتناول تفاصيل
ذلك لاحقًا. يتم رفض الوعد إذا أوقف المستخدم خيار عمليات التنزيل أو كانت إحدى
المَعلمات المقدّمة غير صالحة.
يتيح لك توفير العديد من الطلبات لجلب واحد في الخلفية دمج الأشياء التي تمثل شيئًا واحدًا للمستخدم منطقيًا. على سبيل المثال، يمكن تقسيم فيلم إلى آلاف الموارد (وهو نموذج نموذجي باستخدام MPEG-DASH)، وسيظهر مع موارد إضافية مثل الصور. وقد ينتشر مستوى لعبة ما عبر العديد من موارد JavaScript والصور والصوت. ولكن بالنسبة إلى المستخدم، يتعلق الأمر بـ "الفيلم" أو "المستوى" فقط.
جارٍ استرجاع البيانات الحالية في الخلفية
ويمكنك الحصول على عمليات استرجاع حالية في الخلفية على النحو التالي:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
...من خلال تمرير id لاسترجاع البيانات في الخلفية. تعرض get
القيمة undefined
إذا لم يكن هناك جلب نشط في الخلفية بهذا المعرّف.
يُعتبر استرجاع البيانات في الخلفية "نشطًا" من لحظة تسجيله إلى أن ينجح أو يفشل أو يتم إلغاؤه.
يمكنك الحصول على قائمة بجميع عمليات الجلب النشطة في الخلفية باستخدام 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>> الحصول على الطلبات والردود. الوسيطات المعروضة هنا هي نفسها واجهة برمجة تطبيقات ذاكرة التخزين المؤقت. يؤدي الاتصال بدون وسيطات إلى عرض وعود لجميع السجلات. انظر أدناه للحصول على مزيد من التفاصيل. |
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
هو تسجيل الجلب في الخلفية.
بعد انتهاء هذا الحدث، لن تتوفّر إمكانية الوصول إلى الطلبات والردود التي تم جلبها، لذا إذا كنت تريد الاحتفاظ بها، يمكنك نقلها إلى مكان آخر مثل cache API.
كما هي الحال مع معظم أحداث مشغّلي الخدمات، استخدِم 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 كمسودة تقرير لمجموعة المنتدى.