مساحة التخزين على الويب

هناك العديد من الخيارات المختلفة لتخزين البيانات في المتصفح. ما الخيار الأنسب لاحتياجاتك؟

قد تكون اتصالات الإنترنت متقطّعة أو غير متاحة أثناء التنقّل، ولهذا السبب يُعد الدعم بلا إنترنت والأداء الموثوق به من الميزات الشائعة في تطبيقات الويب التقدّمية. حتى في البيئات اللاسلكية المثالية، يمكن أن يؤدي الاستخدام الحكيم للتخزين المؤقت وتقنيات التخزين الأخرى إلى تحسين تجربة المستخدم بشكل كبير. هناك عدة طرق لتخزين موارد التطبيق الثابتة (HTML وJavaScript وCSS والصور وما إلى ذلك) والبيانات (بيانات المستخدم والمقالات الإخبارية وما إلى ذلك). ولكن ما هو الحل الأفضل؟ كم يمكنك تخزينه؟ كيف يمكنك منع طرده؟

ما الذي يمكنني استخدامه؟

في ما يلي توصية عامة لتخزين الموارد:

تتوافق كل من IndexedDB وCache Storage API في كل المتصفحات الحديثة. وكلاهما غير متزامنين ولن يحظرا سلسلة المحادثات الرئيسية. ويمكن الوصول إليها من خلال كائن window وعاملي الويب ومشغّلي الخدمات، ما يسهّل استخدامها في أي مكان في الرمز.

ماذا عن آليات التخزين الأخرى؟

هناك العديد من آليات التخزين الأخرى المتاحة في المتصفح، ولكن يتم استخدامها بشكل محدود وقد تتسبب في حدوث مشاكل كبيرة في الأداء.

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

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

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

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

تم تصميم واجهة برمجة التطبيقات File System Access API لتسهيل قراءة الملفات وتعديلها على المستخدمين في نظام الملفات المحلي. ويجب أن يمنح المستخدم إذنًا قبل أن تتمكن الصفحة من قراءة أو كتابة أي ملف محلي، ولا تستمر الأذونات عبر الجلسات.

يجب عدم استخدام WebSQL، ونقل الاستخدام الحالي إلى IndexedDB. تمت إزالة الدعم من جميع المتصفحات الرئيسية تقريبًا. توقّفت شركة W3C عن الحفاظ على مواصفات Web SQL في عام 2010، بدون أي خطط مُخطَّط لها لإجراء مزيد من التحديثات.

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

ما هو مقدار ما يمكنني تخزينه من منتجات؟

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

  • يتيح Chrome للمتصفّح استخدام ما يصل إلى% 80 من إجمالي مساحة القرص. وقد يستخدم المصدر ما يصل إلى 60% من إجمالي مساحة القرص. يمكنك استخدام واجهة برمجة تطبيقات StorageManager لتحديد الحد الأقصى للحصة المتوفرة. قد تختلف المتصفحات الأخرى التي تستند إلى Chromium.
    • في وضع التصفّح المتخفي، يقلل Chrome من حجم مساحة التخزين التي يمكن أن يستخدمها أحد المصادر لحوالي 5% من إجمالي مساحة القرص.
    • وفي حال تفعيل المستخدم لـ "محو ملفات تعريف الارتباط وبيانات المواقع الإلكترونية عند إغلاق جميع النوافذ" في Chrome، سيتم خفض حصة مساحة التخزين بشكل كبير إلى 300 ميغابايت تقريبًا كحد أقصى.
    • راجع PR #3896 للحصول على تفاصيل حول تنفيذ Chrome.
  • يمكن لبرنامج Internet Explorer 10 والإصدارات الأحدث تخزين ما يصل إلى 250 ميغابايت، وستظهر رسالة مطالبة إلى المستخدم عند استخدام أكثر من 10 ميغابايت.
  • يتيح فايرفوكس استخدام ما يصل إلى 50% من مساحة القرص الخالية. مجموعة eTLD+1 (على سبيل المثال، example.com وwww.example.com وfoo.bar.example.com) قد تستخدم ما يصل إلى 2 غيغابايت. ويمكنك استخدام StorageManager API لتحديد حجم المساحة التي لا تزال متاحة.
  • يبدو أنّ متصفّح Safari (على كلّ من أجهزة الكمبيوتر المكتبي والأجهزة الجوّالة) يسمح بمساحة تخزين تبلغ 1 غيغابايت تقريبًا. وعند الوصول إلى هذا الحد، سيطلب Safari من المستخدم زيادة الحد الأقصى للحجم الذي يبلغ 200 ميغابايت. لم أتمكّن من العثور على أي مستندات رسمية بشأن هذا الموضوع.
    • في حال إضافة تطبيق ويب تقدّمي (PWA) إلى الشاشة الرئيسية في متصفّح Safari على الأجهزة الجوّالة، يبدو أنّه تم إنشاء حاوية تخزين جديدة، ولا تتم مشاركة أي بيانات بين تطبيق الويب التقدّمي (PWA) ومتصفّح Safari على الأجهزة الجوّالة. بعد بلوغ الحدّ الأقصى لحصة تطبيق ويب تقدّمي (PWA) مثبَّت، لا يبدو أنّ هناك أي طريقة لطلب مساحة تخزين إضافية.

في السابق، إذا كان الموقع الإلكتروني يتجاوز حدًا معيّنًا من البيانات المخزّنة، كان المتصفّح يطلب من المستخدم منح الإذن لاستخدام المزيد من البيانات. على سبيل المثال، إذا استخدم المصدر أكثر من 50 ميغابايت، سيطلب المتصفّح من المستخدم السماح بتخزين ما يصل إلى 100 ميغابايت، ثم يطلب مرة أخرى بزيادات 50 ميغابايت.

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

كيف يمكنني التحقّق من حجم مساحة التخزين المتاحة؟

في العديد من المتصفّحات، يمكنك استخدام StorageManager API لتحديد حجم مساحة التخزين المتاحة للمصدر ومقدار مساحة التخزين التي يستهلكها. تُبلغ هذه الأداة عن إجمالي عدد وحدات البايت المستخدمة في كل من IndexedDB وذاكرة التخزين المؤقت API، وتتيح لك حساب مساحة التخزين المتبقية التقريبية المتاحة.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

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

فحص

أثناء عملية التطوير، يمكنك استخدام "أدوات مطوري البرامج" في متصفّحك لفحص أنواع مساحات التخزين المختلفة ومحو جميع البيانات المخزّنة بسهولة.

تمت إضافة ميزة جديدة في Chrome 88 تتيح لك تجاوز حصة مساحة التخزين للموقع الإلكتروني في "مساحة التخزين". تتيح لك هذه الميزة محاكاة أجهزة مختلفة واختبار سلوك تطبيقاتك في سيناريوهات توفّر قرص منخفض. انتقِل إلى Application (التطبيق) ثم Storage (مساحة التخزين)، وفعِّل مربّع الاختيار محاكاة حصة مساحة التخزين المخصَّصة، وأدخِل أي رقم صالح لمحاكاة حصة مساحة التخزين.

مساحة تخزين أدوات مطوري البرامج

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

كيف يتم التعامل مع تجاوز الحصة المحدّدة؟

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

تعرض كل من IndexedDB وCache API علامة DOMError باسم QuotaExceededError عند تجاوز الحصة المتاحة.

IndexedDB

إذا تجاوز الأصل الحصة المحدّدة، لن تنجح محاولات الكتابة في IndexedDB. سيتم استدعاء معالِج onabort() الخاص بالمعاملة، لتمرير الحدث. سيتضمن الحدث علامة DOMException في خاصية الخطأ. سيؤدي التحقق من الخطأ name إلى عرض QuotaExceededError.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

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

إذا تجاوز الأصل حصته، سيتم رفض محاولات الكتابة في Cache API باستخدام QuotaExceededError DOMException.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

ما هي آلية عمل عملية إخلاء؟

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

تندرج بيانات الموقع الإلكتروني تلقائيًا (بما في ذلك IndexedDB وCache API وما إلى ذلك) ضمن الفئة الأفضل، ما يعني أنّه ما لم يطلب الموقع الإلكتروني مساحة تخزين دائمة، قد يتخلص المتصفّح من بيانات الموقع الإلكتروني وفقًا لتقديره الخاص، مثلاً عندما تكون مساحة التخزين على الجهاز منخفضة.

في ما يلي سياسة الإخلاء التي تهدف إلى بذل أفضل الجهود:

  • ستبدأ المتصفّحات المستندة إلى Chromium في إخراج البيانات عند نفاد مساحة التخزين في المتصفّح، ما يؤدي إلى محو جميع بيانات الموقع الإلكتروني من المصدر الأقل استخدامًا أولاً ثم من المصدر التالي، إلى أن يختفي المتصفّح الحدّ الأقصى.
  • لن يؤدي الإصدار 10+ من Internet Explorer إلى طرد البيانات، ولكنه سيمنع كتابة المصدر مرة أخرى.
  • سيبدأ متصفّح Firefox في إخراج البيانات عند ملء مساحة القرص المتاحة، مع محو جميع بيانات الموقع الإلكتروني من المصدر الأقل استخدامًا أولاً ثم التالي، إلى أن يختفي المتصفّح الحدّ الأقصى.
  • لم يخرج Safari من قبل البيانات، ولكنه طبّق مؤخرًا حدًا أقصى لمدة سبعة أيام على كل مساحات التخزين القابلة للكتابة (انظر أدناه).

بدءًا من الإصدارين 13.4 من نظام التشغيل iOS وiPadOS 13.4 ومتصفّح Safari 13.1 على نظام التشغيل macOS، سيتم تطبيق حدّ أقصى لمدة سبعة أيام على جميع مساحات التخزين البرمجية القابلة للكتابة، بما في ذلك IndexedDB وتسجيل عامل الخدمة وذاكرة التخزين المؤقت لواجهة برمجة التطبيقات. وهذا يعني أن Safari سيخرج كل المحتوى من ذاكرة التخزين المؤقت بعد سبعة أيام من استخدام Safari في حال عدم تفاعل المستخدم مع الموقع. لا تسري سياسة الإخلاء هذه على تطبيقات الويب التقدّمية (PWA) التي تمت إضافتها إلى الشاشة الرئيسية. راجع الحظر الكامل لملفات تعريف الارتباط التابعة لجهات خارجية والمزيد على مدونة WebKit للحصول على تفاصيل كاملة.

ميزة إضافية: ما فائدة استخدام برنامج تضمين في IndexedDB

IndexedDB هي واجهة برمجة تطبيقات منخفضة المستوى تتطلب إعدادًا كبيرًا قبل الاستخدام، ما قد يؤدي إلى صعوبة كبيرة لتخزين البيانات البسيطة. وعلى عكس معظم واجهات برمجة التطبيقات الحديثة القائمة على الوعد، فهي تستند إلى الأحداث. برامج تضمين وعود مثل idb لـ IndexedDB تخفي بعض الميزات الفعالة، والأهم من ذلك، إخفاء الأجهزة المعقدة (مثل المعاملات، وإصدارات المخططات) التي تأتي مع مكتبة IndexedDB.

الخلاصة

لقد ولت أيام التخزين المحدودة ومطالبة المستخدم بتخزين المزيد والمزيد من البيانات. يمكن للمواقع الإلكترونية تخزين جميع الموارد والبيانات التي تحتاج إليها لتشغيلها بشكل فعّال. باستخدام StorageManager API، يمكنك تحديد المقدار المتاح لك ومقدار ما استخدمته. وباستخدام مساحة التخزين الدائمة، يمكنك حمايته من الإخلاء ما لم يزيله المستخدم.

مراجع إضافية

شكرًا

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

صورة الجزء الرئيسي من تقديم "غويلام بولوك" على UnLaunch.