تعديلات على cache.addAll() وImportScripts() لإدخال التعديلات في الإصدار Chrome 71

على المطوّرين الذين يستخدِمون خدمة workers وCache Storage API الانتباه إلى اثنين من التغييرات الصغيرة التي سيتم طرحها في الإصدار 71 من Chrome. يؤدي كلا التغييرَين إلى جعل تنفيذ Chrome أكثر توافقًا مع المواصفات والمتصفّحات الأخرى.

عدم السماح بوظائف importScripts() غير المتزامنة

يطلب العنصر importScripts() من نص worker الرئيسي للخدمت إيقاف تنفيذه الحالي مؤقتًا وتنزيل رمز إضافي من عنوان URL معيّن وتنفيذه إلى أن يكتمل في النطاق الشامل الحالي. بعد الانتهاء من ذلك، يستأنف النص البرمجي الرئيسي لعامل الخدمة تنفيذه. يكون importScripts() مفيدًا عند الرغبة في تقسيم نص التشغيل الرئيسي لمشغّل الخدمات إلى أجزاء أصغر لأسباب تنظيمية، أو جلب رمز تابع لجهة خارجية لإضافة وظيفة إلى مشغّل الخدمات.

تحاول المتصفّحات تخفيف المشاكل المحتملة في الأداء المتعلّقة بـ "تنزيل بعض الرمز البرمجي المتزامن وتنفيذه" من خلال تخزين أي محتوى يتم جلبه عبر importScripts() في ذاكرة التخزين المؤقت تلقائيًا، ما يعني أنّه بعد التحميل المبدئي، لا يتطلّب تنفيذ الرمز البرمجي المستورَد سوى القليل من الموارد.

لكي يعمل ذلك، يجب أن يعرف المتصفّح أنّه لن يتم استيراد أي رمز "مفاجئ" إلى الخدمة العاملة بعد التثبيت الأوّلي. وفقًا لمواصفات موظّف الخدمة، من المفترض أن لا يعمل importScripts() إلا أثناء التنفيذ المتزامن لنص موظّف الخدمة العميق، أو بشكل غير متزامن داخل معالِج install إذا لزم الأمر.

قبل الإصدار 71 من Chrome، كان من الممكن استدعاء importScripts() بشكل غير متزامن خارج معالِج install. بدءًا من الإصدار 71 من Chrome، تؤدي هذه الطلبات إلى طرح استثناء وقت التشغيل (ما لم يتم استيراد عنوان URL نفسه سابقًا في معالِج install)، ما يتطابق مع السلوك في المتصفّحات الأخرى.

بدلاً من رمز مثل هذا:

// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
  importScripts('my-fetch-logic.js');
  event.respondWith(self.customFetchLogic(event));
});

يجب أن يبدو رمز الخدمة على النحو التالي:

// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
  event.respondWith(self.customFetchLogic(event));
});

إيقاف عناوين URL المتكرّرة التي يتم تمريرها إلى cache.addAll() نهائيًا

إذا كنت تستخدم واجهة برمجة التطبيقات Cache Storage API مع عامل خدمة، هناك تغيير صغير آخر في Chrome 71 للتوافق مع المواصفة ذات الصلة. عندما يتم إرسال عنوان URL نفسه عدة مرات إلى طلب واحد لمحاولة cache.addAll()، تنص الموافقة على أنّه يجب رفض الوعد الذي تم إرجاعه من خلال الطلب.

في الإصدارات السابقة من Chrome 71، لم يتم رصد ذلك، وكان يتم تجاهل عناوين URL المكرّرة بشكلٍ فعّال.

لقطة شاشة لرسالة التحذير في وحدة تحكّم Chrome
اعتبارًا من الإصدار 71 من Chrome، ستظهر لك رسالة تحذير مسجَّلة في وحدة التحكّم.

هذه الميزة هي تمهيد لإصدار Chrome 72، حيث ستؤدي عناوين URL المكرّرة إلى cache.addAll() رفض بدلاً من مجرد تحذير مسجّل. إذا كنت تستدعي cache.addAll() كجزء من سلسلة وعد تم تمريرها إلى InstallEvent.waitUntil()، قد يؤدي هذا الرفض إلى تعذُّر تثبيت مشغّل الخدمة، كما هو شائع.

في ما يلي الحالات التي قد تواجه فيها مشكلة:

const urlsToCache = [
  '/index.html',
  '/main.css',
  '/app.js',
  '/index.html', // Oops! This is listed twice and should be removed.
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
  );
});

لا ينطبق هذا القيد إلا على عناوين URL الفعلية التي يتم تمريرها إلى cache.addAll()، ولن يؤدي الاحتفاظ مؤقتًا بما ينتهي به الأمر إلى استجابتَين متكافئتَين تتضمّنان عناوين URL مختلفة، مثل '/' و'/index.html'، إلى رفض المحتوى.

اختبار تنفيذ الخدمة العاملة على نطاق واسع

تم تنفيذ مهام الخدمة على نطاق واسع في جميع المتصفّحات الرئيسية التي تعمل باستمرار في هذه المرحلة. إذا كنت تختبر تطبيقك الويب التقدّمي بانتظام على عدد من المتصفّحات، أو إذا كان لديك عدد كبير من المستخدمين الذين لا يستخدمون Chrome، من المرجّح أنّك رصدت التناقض وغيّرت الرمز البرمجي. ولكن في حال عدم ملاحظتك لهذا السلوك في المتصفّحات الأخرى، أردنا الإشارة إلى هذا التغيير قبل تغيير سلوك Chrome.