تخزين الموارد في ذاكرة التخزين المؤقت أثناء وقت التشغيل

قد نادرًا ما تُستخدَم بعض مواد العرض في تطبيق الويب، أو قد تكون كبيرة جدًا، أو قد تختلف حسب جهاز المستخدم (مثل الصور المتجاوبة مع مختلف الأجهزة) أو اللغة. في هذه الحالات، قد يكون التخزين المؤقت للصفحات مضادة للأنماط، وعليك الاعتماد على التخزين المؤقت في وقت التشغيل بدلاً من ذلك.

في Workbox، يمكنك التعامل مع التخزين المؤقت لمواد العرض أثناء وقت التشغيل باستخدام وحدة workbox-routing لمطابقة المسارات، والتعامل مع استراتيجيات التخزين المؤقت لها من خلال وحدة workbox-strategies.

استراتيجيات التخزين المؤقت

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

  • تستخدم ميزة "القديمة أثناء إعادة التحقُّق" استجابة "مخزَّنة مؤقتًا" للطلب إذا كان متاحًا وتُعدِّل ذاكرة التخزين المؤقت في الخلفية باستجابة من الشبكة. وبالتالي، إذا لم تكن مادة العرض مخزّنة مؤقتًا، ستنتظر استجابة الشبكة وتستخدمها. وهذه استراتيجية آمنة إلى حدّ ما، إذ تعمل على تحديث إدخالات ذاكرة التخزين المؤقت التي تعتمد عليها بانتظام. ومن ناحية أخرى، يكمن الجانب السلبي في هذه الميزة في أنها تطلب دائمًا مادة عرض من الشبكة في الخلفية.
  • تحاول خدمة Network First تلقّي رد من الشبكة أولاً. في حال تلقّي استجابة، يتم تمرير هذه الاستجابة إلى المتصفِّح وحفظها في ذاكرة التخزين المؤقت. إذا تعذّر طلب الشبكة، سيتم استخدام آخر استجابة مخزَّنة مؤقتًا، ما يمكِّن الوصول إلى مادة العرض بلا اتصال بالإنترنت.
  • تفحص دالة Cache First ذاكرة التخزين المؤقت بحثًا عن استجابة أولاً وتستخدمها إذا كانت متوفّرة. إذا لم يكن الطلب في ذاكرة التخزين المؤقت، يتم استخدام الشبكة وتتم إضافة أي استجابة صالحة إلى ذاكرة التخزين المؤقت قبل تمريرها إلى المتصفح.
  • الشبكة فقط تفرض الاستجابة على أن ترد من الشبكة.
  • يؤدي استخدام ذاكرة التخزين المؤقت فقط إلى فرض تلقي الاستجابة من ذاكرة التخزين المؤقت.

يمكنك تطبيق هذه الاستراتيجيات لاختيار الطلبات باستخدام الطرق التي تقدّمها منصة workbox-routing.

تطبيق استراتيجيات التخزين المؤقت مع مطابقة المسارات

ويعرض workbox-routing طريقة registerRoute لمطابقة المسارات والتعامل معها من خلال استراتيجية تخزين مؤقت. تقبل registerRoute كائن Route الذي يقبل بدوره وسيطَتين:

  1. سلسلة أو تعبير عادي أو استجابة اتصال مطابقة لتحديد معايير مطابقة المسار.
  2. تمثّل هذه السمة معالجًا للمسار، وعادةً ما تكون استراتيجية مقدّمة من workbox-strategies.

يُفضَّل أن تتم مطابقة المسارات، لأنّها توفّر كائن سياق يتضمّن الكائن Request وسلسلة عنوان URL للطلب وحدث الجلب، بالإضافة إلى قيمة منطقية ممّا إذا كان الطلب من المصدر نفسه.

يعالج المعالج بعد ذلك المسار المطابق. في المثال التالي، يتم إنشاء مسار جديد يطابق طلبات الصور من المصدر نفسه الواردة، مع تطبيق ذاكرة التخزين المؤقت أولاً، مع الرجوع إلى استراتيجية الشبكة.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';

// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
  return sameOrigin && request.destination === 'image'
}, new CacheFirst());

// Register the new route
registerRoute(imageRoute);

استخدام ذاكرات تخزين مؤقت متعددة

يسمح لك "إطار العمل" بتجميع الردود المخزّنة مؤقتًا في مثيلات Cache منفصلة باستخدام خيار cacheName المتاح في الاستراتيجيات المجمّعة.

في المثال التالي، تستخدم الصور استراتيجية قديمة أثناء إعادة التحقق، في حين تستخدم أصول CSS وJavaScript استخدام ذاكرة التخزين المؤقت أولاً لاستراتيجية الشبكة. يؤدي مسار كل مادة عرض إلى وضع الردود في ذاكرات تخزين مؤقت منفصلة، وذلك من خلال إضافة السمة cacheName.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';

// Handle images:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image'
}, new StaleWhileRevalidate({
  cacheName: 'images'
}));

// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts'
}));

// Handle styles:
const stylesRoute = new Route(({ request }) => {
  return request.destination === 'style';
}, new CacheFirst({
  cacheName: 'styles'
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
لقطة شاشة لقائمة مثيلات "ذاكرة التخزين المؤقت" في علامة تبويب "التطبيق" ضمن "أدوات مطوري البرامج في Chrome" تظهر ثلاث ذاكرات تخزين مؤقت مميزة: إحداهما باسم 'scripts'، والأخرى باسم 'styles'، والأخرى باسم 'images'.
عارض مساحة تخزين ذاكرة التخزين المؤقت في لوحة "التطبيقات" ضِمن "أدوات مطوري البرامج في Chrome" ويتمّ تخزين الردود الخاصة بأنواع مواد العرض المختلفة في ذاكرات تخزين مؤقت منفصلة.

ضبط تاريخ انتهاء صلاحية لإدخالات ذاكرة التخزين المؤقت

ويجب الانتباه إلى حصص التخزين عند إدارة ذاكرات التخزين المؤقت للعاملين في الخدمات. تبسّط ExpirationPlugin صيانة ذاكرة التخزين المؤقت ويتم عرضها من خلال workbox-expiration. ولاستخدامه، حدِّده في إعدادات استراتيجية التخزين المؤقت:

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'images',
  plugins: [
    new ExpirationPlugin({
      maxAgeSeconds: 60 * 60 * 24 * 30,
    })
  ]
}));

// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
    })
  ]
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
.

قد يكون الالتزام بحصص مساحة التخزين أمرًا معقدًا. من الممارسات الجيدة مراعاة المستخدمين الذين ربما يواجهون ضغطًا لمساحة التخزين، أو يريدون تحقيق أقصى استفادة من مساحة التخزين المتاحة لهم. يمكن أن تساعدك أزواج ExpirationPlugin من Workbox في تحقيق هذا الهدف.

اعتبارات مشتركة المصدر

يختلف التفاعل بين مشغّل الخدمات والأصول المتعدّدة المصادر إلى حدّ كبير مقارنةً بمواد العرض ذات المصدر نفسه. تُعدّ مشاركة الموارد المتعدّدة المصادر (CORS) عملية معقّدة، ويمتد هذا التعقيد إلى كيفية تعاملك مع الموارد المتعدّدة المصادر في مشغّل الخدمات.

استجابات معتمة

عند تقديم طلب من مصادر متعددة في وضع no-cors، يمكن تخزين الاستجابة في ذاكرة تخزين مؤقت لعامل الخدمة، بل يمكن استخدامها مباشرةً في المتصفِّح. ومع ذلك، لا يمكن قراءة نص الاستجابة بذاته عبر JavaScript. ويُعرف ذلك باسم استجابة مبهمة.

الردود غير الواضحة هي إجراء أمني يهدف إلى منع فحص مادة عرض متعددة المصادر. لا يزال بإمكانك تقديم طلبات للحصول على مواد عرض من مصادر متعددة، وحتى تخزينها مؤقتًا، ولكن لن تتمكّن من قراءة نص الاستجابة أو حتى قراءة رمز الحالة الخاص به.

تذكُّر تفعيل وضع سياسة مشاركة الموارد المتعددة المصادر (CORS)

حتى في حال تحميل مواد العرض من مصادر متعددة التي تضبط عناوين CORS المتساهِلة التي تسمح لك بقراءة الردود، قد يظل نص الاستجابة من مصادر متعددة معتمًا. على سبيل المثال، سيؤدي رمز HTML التالي إلى تشغيل طلبات no-cors التي تؤدي إلى استجابات مبهمة بغض النظر عن عناوين CORS التي تم ضبطها:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

لتشغيل طلب cors بشكل واضح يؤدي إلى استجابة غير مبهمة، يجب تفعيل وضع CORS بشكل صريح من خلال إضافة سمة crossorigin إلى HTML:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

من المهم تذكُّر ذلك عندما يتم تحميل الموارد الفرعية في ذاكرة التخزين المؤقت للمسارات في وقت التشغيل.

قد لا يخزِّن مربّع العمل الردود المبهمة مؤقتًا.

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

إذا كنت بحاجة إلى تخزين استجابة مبهمة في Workbox في ذاكرة التخزين المؤقت، يجب استخدام استراتيجية تعتمد على الشبكة أولاً أو استراتيجية للتحقّق من مدى التوفّر أثناء عملية المعالجة. نعم، يعني ذلك أنّه سيستمر طلب مادة العرض من الشبكة في كل مرة، لكنّ ذلك يضمن عدم استمرار الاستجابات التي تعذّر إكمالها، وسيتم استبدالها في النهاية بردود قابلة للاستخدام.

إذا كنت تستخدم استراتيجية أخرى للتخزين المؤقت وتم عرض استجابة مبهمة، سيحذرك Workbox من أنه لم يتم تخزين الاستجابة مؤقتًا عندما تكون في وضع التطوير.

فرض التخزين المؤقت للاستجابات الغامضة

إذا كنت متأكّدًا تمامًا من أنّك تريد تخزين استجابة مبهمة في ذاكرة التخزين المؤقت باستخدام استراتيجية التخزين المؤقت أولاً أو استراتيجية التخزين المؤقت فقط، يمكنك فرض إجراء ذلك على Workbox باستخدام وحدة workbox-cacheable-response:

import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cdnRoute = new Route(({url}) => {
  return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200]
    })
  ]
}))

registerRoute(cdnRoute);

"الردود غير الواضحة" وواجهة برمجة التطبيقات navigator.storage

لتجنب تسرُّب المعلومات عبر النطاقات، تمت إضافة مساحة متروكة كبيرة إلى حجم الاستجابة الغامضة المستخدمة لحساب حدود حصة التخزين. ويؤثر هذا في كيفية إبلاغ navigator.storage API عن حصص مساحة التخزين.

وتختلف هذه المساحة المتروكة حسب المتصفح، ولكن بالنسبة إلى Chrome، يكون الحد الأدنى للحجم الذي تساهم به أي استجابة واحدة فارغة في ذاكرة التخزين المؤقت في إجمالي مساحة التخزين المستخدمة هو 7 ميغابايت تقريبًا. يجب أن تضع ذلك في اعتبارك عند تحديد عدد الاستجابات المبهمة التي تريد تخزينها مؤقتًا، حيث يمكنك بسهولة تجاوز حصص التخزين في وقت أقرب بكثير مما تتوقع.