لا يتم إنشاء كل مساحة التخزين بشكل متساوٍ: التعريف بـ "حِزم مساحة التخزين"

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

ما المشكلة التي يحلها معيار التخزين؟

عادةً، عندما تنفد مساحة التخزين لدى المستخدم على جهازه، تُفقد البيانات المُخزنة باستخدام واجهات برمجة التطبيقات، مثل IndexedDB أو localStorage، بدون أن يتمكن المستخدم من التدخل. وهناك وسيلة لجعل مساحة التخزين دائمة من خلال استدعاء طريقة persist() لواجهة StorageManager. وتطلب في الوقت ذاته من المستخدم النهائي الإذن وتغير مساحة التخزين لتبقى مستمرة بمجرد منحها:

const persisted = await navigator.storage.persist();
if (persisted) {
  /* Storage will not be cleared except by explicit user action. */
}

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

واجهة برمجة تطبيقات حزم التخزين

تتمثل الفكرة الأساسية لواجهة Storage Buckets API في منح المواقع الإلكترونية إمكانية إنشاء حِزم تخزين متعددة، حيث يمكن للمتصفِّح اختيار حذف كل حزمة بشكل مستقل عن الحِزم الأخرى. يتيح ذلك للمطورين تحديد أولويات الإخلاء للتأكد من عدم حذف البيانات الأكثر قيمة.

مثال على حالة الاستخدام

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

واجهة تطبيق البريد الإلكتروني
تطبيق للبريد الإلكتروني يتضمن حِزم تخزين منفصلة للبريد الوارد والمسودات. (لأغراض التوضيح فقط، لا يعكس ذلك بالضرورة طريقة عمل Gmail.)

استخدام واجهة برمجة تطبيقات Storage Storage

إنشاء حزمة مساحة تخزين جديدة

يمكن إنشاء حزمة تخزين جديدة باستخدام الطريقة open() على واجهة StorageBucketManager.

// Create a storage bucket for emails that are synchronized with the
// server.
const inboxBucket = await navigator.storageBuckets.open('inbox');

إنشاء حزمة مساحة تخزين جديدة ثابتة

لضمان الاحتفاظ بحزمة التخزين، يمكنك تمرير وسيطتَي الخيارَين durability وpersisted إلى الطريقة open():

  • تحدِّد السمة persisted ما إذا كان يجب الاحتفاظ بحزمة التخزين أم لا. القيم المسموح بها هي false (تلقائية) أو true.
  • توفّر علامة durability تلميحًا للمتصفح يساعده في مقايضة أداء الكتابة بتفادي انخفاض مخاطر فقدان البيانات في حال انقطاع التيار الكهربائي. القيم المسموح بها هي 'relaxed' (الخيار التلقائي) أو 'strict':

    • تحاول 'strict' حزمة تقليل مخاطر فقدان البيانات عند انقطاع التيار الكهربائي. قد يكون هذا نتيجة انخفاض مستوى الأداء، ما يعني أنّ اكتمال عمليات الكتابة قد يستغرق وقتًا أطول وقد يؤثر في أداء النظام بشكل عام ويستهلك المزيد من طاقة البطارية وقد يؤدي إلى تلف جهاز التخزين بشكل أسرع.
    • قد "تنسى" مجموعات البيانات 'relaxed' عمليات الكتابة التي اكتملت خلال الثواني القليلة الماضية، عند فقدان الطاقة. في المقابل، قد تؤدّي كتابة البيانات في هذه المجموعات إلى الحصول على خصائص أداء أفضل، وقد تسمح بإطالة عمر البطارية، وقد ينتج عنها عمر أطول لجهاز التخزين. بالإضافة إلى ذلك، لن يؤدي انقطاع الطاقة إلى تلف البيانات بمعدّل أعلى مقارنةً بحِزم 'strict'.
// Create a storage bucket for email drafts that only exist on the client.
const draftsBucket = await navigator.storageBuckets.open('drafts', {
  durability: 'strict', // Or `'relaxed'`.
  persisted: true, // Or `false`.
});

الوصول إلى واجهات برمجة التطبيقات للتخزين من حزمة تخزين

ترتبط كل حزمة مساحة تخزين بواجهات برمجة تطبيقات التخزين، على سبيل المثال، IndexedDB أو واجهة ذاكرة التخزين المؤقت أو واجهة الملف. تعمل واجهات برمجة التطبيقات للتخزين على النحو المعتاد، ولكن يتم تسجيل نقطة الدخول من واجهة StorageBucket، مثل StorageBucket.indexedDB.

const inboxDb = await new Promise(resolve => {
  const request = inboxBucket.indexedDB.open('messages');
  request.onupgradeneeded = () => { /* migration code */ };
  request.onsuccess = () => resolve(request.result);
  request.onerror = () => reject(request.error);
});

مراجع مفيدة