في عام 2015، أطلقنا ميزة "المزامنة في الخلفية" التي تتيح لبرنامج عامل الخدمة تأجيل العمل إلى حين توفّر اتصال للمستخدم. وهذا يعني أنّه يمكن للمستخدم كتابة رسالة والنقر على "إرسال" ومغادرة الموقع الإلكتروني مع العلم أنّه سيتم إرسال الرسالة إما الآن أو عند توفّر اتصال بالإنترنت.
وهي ميزة مفيدة، ولكنها تتطلّب أن يكون عامل الخدمة نشطًا طوال مدة عملية الجلب. لا يشكّل ذلك مشكلة بالنسبة إلى المهام القصيرة، مثل إرسال رسالة، ولكن إذا استغرقت المهمة وقتًا طويلاً، سيوقف المتصفح عامل الخدمة، وإلا سيشكّل ذلك خطرًا على خصوصية المستخدم وعمر البطارية.
ماذا لو كنت بحاجة إلى تنزيل محتوى قد يستغرق وقتًا طويلاً، مثل فيلم أو ملفات بودكاست أو مستويات إحدى الألعاب؟ هذا هو الغرض من ميزة استرجاع البيانات في الخلفية.
تتوفّر ميزة Background Fetch تلقائيًا منذ الإصدار 74 من Chrome.
إليك عرض توضيحي سريع مدته دقيقتان يعرض الحالة التقليدية للأشياء مقارنةً باستخدام Background Fetch:
آلية العمل
يعمل استرجاع البيانات في الخلفية على النحو التالي:
- تطلب من المتصفّح تنفيذ مجموعة من عمليات الجلب في الخلفية.
- ويجلب المتصفّح هذه العناصر ويعرض للمستخدم مدى تقدّمه.
- بعد اكتمال عملية الجلب أو تعذّرها، يفتح المتصفّح عامل الخدمة ويُطلق حدثًا لإعلامك بما حدث. هذا هو المكان الذي يمكنك فيه تحديد ما يجب فعله بالردود، إن وُجدت.
إذا أغلق المستخدم صفحات موقعك الإلكتروني بعد الخطوة 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)، وقد يتضمّن موارد إضافية، مثل الصور. يمكن أن ينتشر مستوى اللعبة على العديد من موارد JavaScript والصور والصوت. ولكن بالنسبة إلى المستخدم، يكون ذلك مجرد "الفيلم" أو "المستوى".
الحصول على عملية استرجاع بيانات في الخلفية حالية
يمكنك الحصول على عملية جلب بيانات في الخلفية حالية على النحو التالي:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
…من خلال تمرير المعرّف لعملية الجلب في الخلفية التي تريدها. تعرض الدالة 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 هل يمكن الوصول إلى الطلبات/الردود الأساسية؟ بعد أن تصبح القيمة "false"، لا يمكن استخدام |
الطُرق | |
abort() |
تعرض هذه السمة Promise<boolean> إلغاء عملية الجلب في الخلفية. يتم حلّ الوعد الذي تم إرجاعه بالقيمة true إذا تم إلغاء عملية الجلب بنجاح. |
matchAll(request, opts) |
تعرض هذه السمة Promise<Array<BackgroundFetchRecord>> طلبات البحث والردود. تكون الوسيطات هنا هي نفسها الخاصة بواجهة Cache 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');
}
});
مراجع إضافية
تصحيح: أشارت نسخة سابقة من هذه المقالة بشكل خاطئ إلى أنّ ميزة Background Fetch هي "معيار ويب". لا تتوفّر واجهة برمجة التطبيقات حاليًا في مسار المعايير، ويمكن العثور على المواصفات في WICG كمسودة تقرير لمجموعة المنتدى.