في عام 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
. سأتناول
تفاصيل ذلك لاحقًا. يتم رفض الوعد إذا أوقف المستخدم عمليات التنزيل أو إذا كانت إحدى المَعلمات المقدَّمة غير صالحة.
من خلال تقديم العديد من الطلبات لإجراء عملية جلب واحدة في الخلفية، يمكنك دمج العناصر التي تُعدّ من الناحية المنطقية عنصرًا واحدًا للمستخدم. على سبيل المثال، يمكن تقسيم فيلم إلى آلاف الموارد (عادةً ما يكون ذلك باستخدام 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> إيقاف جلب البيانات في الخلفية يتم حلّ الوعد الذي تم إرجاعه بقيمة صحيحة إذا تم إلغاء عملية الجلب بنجاح. |
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
هو تسجيل الجلب في الخلفية.
بعد هذا الحدث، لن يعود بإمكانك الوصول إلى الطلبات والردود التي تم جلبها، لذا إذا أردت الاحتفاظ بها، عليك نقلها إلى مكان آخر، مثل واجهة برمجة التطبيقات الخاصة بالخزين المؤقت.
كما هو الحال مع معظم أحداث الخدمة، استخدِم event.waitUntil
حتى يعرف العامل في الخدمة وقت اكتمال الحدث.
على سبيل المثال، في Worker الخدمة:
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 كمشروع مسودة تقرير مجموعات المنتدى.