في عام 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 الحجم الإجمالي لنصّ الردود (بعد إزالة ضغطها باستخدام برنامج gzip) وعلى الرغم من أنّ هذه الخطوة اختيارية، إلا أنّنا ننصحك بشدة بتقديمه. ويُستخدَم لإعلام المستخدم بحجم عملية التنزيل وتقديم معلومات عن مستوى التقدّم. وفي حال عدم تقديم هذه المعلومات، سيُعلم المتصفّح المستخدم بأنّ الحجم غير معروف، ونتيجةً لذلك، قد يلغي المستخدم عملية التنزيل. إذا تجاوز عدد عمليات تنزيل البيانات في الخلفية العدد المحدَّد هنا، سيتم إلغاء هذه العمليات. ولا بأس
على الإطلاق إذا كانت حجم عملية التنزيل أصغر من |
ترجع "backgroundFetch.fetch
" وعودًا يتم حلّه من خلال "BackgroundFetchRegistration
". سأتناول تفاصيل ذلك لاحقًا. يتم رفض الوعد إذا أوقف المستخدم عمليات التنزيل أو إذا كانت إحدى المَعلمات المقدَّمة غير صالحة.
يتيح لك تقديم العديد من الطلبات لجلب خلفية واحدة دمج الأشياء التي تمثل شيئًا واحدًا منطقيًا للمستخدم. على سبيل المثال، يمكن تقسيم الفيلم إلى 1,000 مورد من الموارد (كما هو الحال مع 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 كمسودة تقرير مجموعة المنتدى.