تخزين البيانات محليًّا في المتصفح عبر قاعدة البيانات IndexedDB
ملخص تمهيدي
تُعَدّ قاعدة البيانات IndexedDB البُنية الأساسية الأكثر تطورًا لتخزين البيانات المحلّية داخل المتصفِّح، إذ توفِّر إمكانيّات شبه كاملة لإدارة كميات كبيرة من البيانات البنيويّة (Structured Data) وغير البنيويّة (Unstructured Data) على جهاز المستخدم دون الحاجة إلى خوادم خارجية أثناء التصفُّح الآني. يقدّم هذا المقال تحليلًا معمقًا للهندسة الداخلية لـ IndexedDB، وطبيعة عملها، وأبرز حالات الاستخدام العملية، وأفضل الممارسات الأمنية، مع مقارنة تفصيلية بينها وبين حلول التخزين المحلي الأخرى في الويب. كما يستكشف المقال الإشكالات الشائعة، واستراتيجيات الفهرسة والأداء، ودور IndexedDB في تطبيقات الويب التقدّمية (PWAs)، وأخيرًا مستقبل التقنية في ظل المعايير الناشئة.
فهرس المحتويات
-
مقدمة تاريخية لتخزين البيانات في المتصفح
-
النشأة والتطوّر المعياري لـ IndexedDB
-
بنية قاعدة البيانات: المفاهيم الأساسية
-
واجهة البرمجة (API): نمط الأحداث ووعود Promises
-
الفهرسة (Indexing) وهيكلة الجداول (Object Stores)
-
المعاملات (Transactions) والاتساق (Consistency)
-
إدارة الإصدارات وترحيل المخططات (Schema Migration)
-
التكامل مع Service Workers وتطبيقات الويب التقدّمية
-
أفضل الممارسات للأداء والكفاءة
-
الأمن والخصوصية: التحديات والحلول
-
مقارنة شاملة مع LocalStorage و WebSQL
-
دراسات حالة وتطبيقات عملية
-
مشكلات شائعة واستراتيجيات التصحيح
-
مستقبل IndexedDB ومعايير الويب القادمة
-
الخاتمة
-
المراجع
1. مقدمة تاريخية لتخزين البيانات في المتصفح
منذ بداية الويب الديناميكي في منتصف تسعينيات القرن الماضي، ظهرت الحاجة إلى آلية تسمح لتطبيقات الويب بتخزين معلومات متعلقة بالمستخدم على جهازه المحلي. في البداية اقتصر الأمر على ملفات تعريف الارتباط (Cookies) التي لا تتجاوز سعتها 4 كيلوبايت، ولا تُعدّ مناسبة لأكثر من تخزين معرِّف جلسة مؤقت. لاحقًا، قدَّم HTML5 في عام 2009 معيارين جديدين: LocalStorage و SessionStorage، يوفر كل منهما سعةً تصل إلى 5 ميغابايت تقريبًا لكل نطاق. إلّا أنّ التطبيقات الحديثة احتاجت إلى تخزين عشرات إلى مئات الميغابايت من البيانات البنيوية، كالخرائط غير المتصلة، ومكتبات الوسائط، وتخزين حالات الألعاب، فبرزت WebSQL (لاحقًا أُهملت) ثم IndexedDB كحل قياسي مدعوم من كبرى المتصفحات.
2. النشأة والتطوّر المعياري لـ IndexedDB
-
2010: قدّمت Mozilla و Microsoft مسودة أولية لـ IndexedDB إلى W3C.
-
2015: انتقلت المسودة إلى مرحلة Candidate Recommendation؛ بدأت المتصفحات في دعمها افتراضيًا.
-
2021: نُشر IndexedDB Level 3 مع تحسينات على واجهات Promises ومضاعفة الأداء في عمليات البحث والفهرسة.
-
2023: إطلاق Storage Foundation API كطبقة منخفضة المستوى قد تتكامل مع IndexedDB مستقبلاً لتوحيد التخزين عبر المنصات.
3. بنية قاعدة البيانات: المفاهيم الأساسية
3.1 قاعدة البيانات (Database)
يحتوي كل نطاق (Origin) على عدد غير محدود من قواعد البيانات، تُنشأ باسم فريد وإصدار رقمي. تُخزَّن هذه القواعد غالبًا في ملفات بنية LevelDB أو SQLite في القرص المحلي للمتصفح.
3.2 مخازن الكائنات (Object Stores)
تشبه الجداول في قواعد SQL غير أن كل سجل يُخزَّن ككائن JavaScript متسلسل إلى Structured Clone Algorithm. يدعم المخزن مفتاحًا أساسيًّا (Primary Key) إمّا متولِّد ذاتيًا Sequence أو مشتقًا من خاصية داخل الكائن.
3.3 المفاتيح (Keys) والقِيَم (Values)
تدعم المفاتيح أنماط «سلسلة نصية»، «رقم»، «تاريخ»، أو «مصفوفة». القيم قد تكون أي كائن قابل للاستنساخ البنيوي، بما في ذلك مصفوفات TypedArray، و Blob، و File، وحتى كائنات ImageBitmap.
4. واجهة البرمجة (API): نمط الأحداث ووعود Promises
أضيفت واجهة IDBFactory إلى كائن window، وتوفِّر الطرق indexedDB.open()، deleteDatabase()، و databases(). ابتداءً من Level 2 أصبح بإمكان المطورين استخدام الصيغة المعتمدة على Promises عبر window.indexedDB.databases() وIDBRequest المغلف في IDBOpenDBRequest. ظهر أيضًا wrap/unwrap في مكتبة idb التي تبسِّط التعامل عبر async/await.
javascriptimport { openDB } from 'idb';
const db = await openDB('BooksDB', 1, {
upgrade(database) {
database.createObjectStore('books', { keyPath: 'isbn' });
database.createObjectStore('authors', { keyPath: 'id', autoIncrement: true });
},
});
5. الفهرسة (Indexing) وهيكلة الجداول (Object Stores)
يُنشأ الفهرس بواسطة createIndex() لتسريع الاستعلامات الشرطية دون المساس بسلامة البيانات الأصلية. يسمح الفهرس المركّب (Compound Index) بفهرسة أكثر من خاصية واحدة، مما يقلل الحاجة لفا
حث الأنظمة الخارجية. تُحدَّد سمة unique لمنع التكرار، وmultiEntry للتعامل مع خصائص مصفوفية.
6. المعاملات (Transactions) والاتساق (Consistency)
كل عملية قراءة أو كتابة يجب أن تتم داخل معاملة، والتي يمكن أن تكون من نوع readonly أو readwrite. يضمن نموذج المعاملات العزل التسلسلي (Serializability)، ما يمنع ظهور حالات قِراءة قِيَم وسطية أو انتهاك سلامة البيانات. تُلغى المعاملة تلقائيًّا عند خطأٍ غير معالَج، ويعود مؤشر (Cursor) إلى حالته الأصلية.
7. إدارة الإصدارات وترحيل المخططات (Schema Migration)
عند زيادة رقم الإصدار في indexedDB.open(), تُستدعى دالة onupgradeneeded مرة واحدة لكل مستخدم. يجب على المطوّر تنفيذ ترحيل المخطط داخل هذه الدالة لإنشاء مخازن جديدة أو تعديل الفهارس دون فقدان البيانات.
javascriptrequest.onupgradeneeded = event => {
const db = event.target.result;
if (!db.objectStoreNames.contains('orders')) {
db.createObjectStore('orders', { keyPath: 'orderId' });
}
const store = event.currentTarget.transaction.objectStore('books');
store.createIndex('by_title', 'title', { unique: false });
};
8. التكامل مع Service Workers وتطبيقات الويب التقدّمية (PWAs)
تسمح Service Workers بتخزين الموارد مؤقّتًا في Cache Storage واسترجاعها دون اتصال. لكن البيانات الديناميكية—كتفضيلات المستخدم وقوائم القراءة—تُحفظ بكفاءة أكبر في IndexedDB. يمكن للـ Service Worker الوصول إلى IndexedDB داخل حدث fetch لإنشاء إستراتيجية Stale‑While‑Revalidate أو Background Sync لحفظ الطلبات أثناء انقطاع الشبكة.
9. أفضل الممارسات للأداء والكفاءة
-
تقسيم المخازن: تجنُّب تخزين أنواع بيانات غير متجانسة في نفس المخزن.
-
الدفعات (Batching): دمج عمليات الكتابة في معاملة واحدة لتقليل التبديل السياقي.
-
الفهارس الانتقائية: إنشاء فهارس فقط للاستعلامات الحرجة، لأن كل فهرس يستهلك مساحة ووقت تحديث.
-
التخزين الثنائي (Binary Storage): ضغط البيانات الكبيرة باستخدام Compression Streams API قبل الحفظ.
-
Lazy Loading: تحميل السجلات تدريجيًا باستخدام المؤشرات (Cursors) لمنع تجميد واجهة المستخدم.
10. الأمن والخصوصية: التحديات والحلول
-
عزل النطاق (Origin Isolation): لا يمكن لتطبيقات مختلفة تبادل البيانات مباشرة.
-
سياسة مساحة التخزين (Storage Access Policy): المتصفحات تفرض حصصًا (Quota) وعند تجاوزها يُطلب إذن المستخدم أو يُحذف أقدم محتوى.
-
هجمات XSS: يجب تعقيم البيانات قبل عرضها مجددًا في DOM.
-
التشفير الطرفي (Client‑Side Encryption): يُوصى بتشفير البيانات الحساسة قبل تخزينها. مكتبة
crypto.subtleتوفر خوارزميات AES‑GCM.
11. مقارنة شاملة مع حلول التخزين الأخرى
| المعيار | IndexedDB | LocalStorage | WebSQL (مهمل) |
|---|---|---|---|
| سعة التخزين | مئات ميغابايت | ~5 ميغابايت | حسب الحصة |
| نوع البيانات | كائنات معقدة | نصوص فقط | جداول SQL |
| واجهة البرمجة | غير متزامنة | متزامنة | شبه متزامنة |
| الفهرسة والاستعلام | فهارس مدمجة | لا يوجد | SQL ميزة أساسية |
| الدعم القياسي | W3C حيّ | WHATWG | مهمل منذ 2019 |
| خيوط التنفيذ | Web Worker | لا يدعم | لا يدعم |
| الأمن/التعاقدية | عزل النطاق | عزل النطاق | عزل النطاق |
12. دراسات حالة وتطبيقات عملية
12.1 تطبيق خرائط غير متصلة بالإنترنت
قامت منصة خرائط مفتوحة المصدر بتخزين مربعات الصور (Map Tiles) بصيغة Blob في مخزن tiles. تجاوز الحجم 150 ميغابايت، مما يجعل IndexedDB الخيار الوحيد الممكن. اعتمدت الاسترداد المرحلي والتنظيف الدوري للمحتوى القديم.
12.2 قارئ كتب إلكترونية (e‑Reader)
يُخزّن كل كتاب بصيغة EPUB مفككَك إلى فصول داخل المخزن، مع فهرس على العناوين. يمكّن هذا التصميم من استئناف القراءة من آخر صفحة حتى دون إنترنت، ويتيح البحث السريع في المحتوى.
13. مشكلات شائعة واستراتيجيات التصحيح
| المشكلة | السبب المحتمل | الحل الموصى به |
|---|---|---|
QuotaExceededError |
تجاوز الحد المسموح للنطاق | احذف المحتوى المؤقت أو اطلب إذنًا أكبر |
| تعليق واجهة المستخدم أثناء الكتابة | عمليات ضخمة في الخيط الرئيسي | انقل المنطق إلى Web Worker واستخدم دفعات |
VersionError عند الترقية |
نافذة تبويب أخرى تفتح قاعدة البيانات | أغلق الجلسات الأخرى أو عُدّل منطق الكشف |
| فهرس لا يستجيب للاستعلام | فهرس غير مركَّب أو مفقود | أعد بناء الفهرس باستخدام حقل مناسب |
14. مستقبل IndexedDB ومعايير الويب القادمة
-
IDB Observability API: قيد الاقتراح لتمكين المراقبة اللحظية للتغييرات على البيانات.
-
Portable Web Publications: ستستفيد من التخزين المحلي للكتب التفاعلية في هيئة موحدة.
-
Storage Buckets: معيار قادم لتصنيف البيانات حسب الطابع الزمني لتسهيل الحذف الانتقائي.
-
WASM + IndexedDB: تكامل وثيق يوفر قواعد بيانات مثل SQLite تعمل بكفاءة داخل WebAssembly مع تخزين الخلفية في IndexedDB.
15. الخاتمة
أثبتت IndexedDB نفسها كأساس موثوق ومعياري لتخزين البيانات محليًّا داخل المتصفح، متجاوزةً القيود التاريخية لحلول سابقة من حيث السعة والمرونة والأداء. من خلال فهم بنية المخازن والمعاملات والفهارس وتطبيق أفضل الممارسات الأمنية، يستطيع المطوّر بناء تطبيقات ويب غنيّة بالميزات تعمل بكفاءة حتى في ظروف الشبكة المتقطّعة. ومع التطوّر المستمر لمعايير الويب، من المتوقّع أن تُدمج IndexedDB إلى جانب واجهات جديدة تعظّم القيمة للمستخدم النهائي وتبسط عبء التطوير.
16. المراجع
-
W3C. Indexed Database API (Level 3) Specification. 2024.
-
Google Developers. MDN Web Docs – Using IndexedDB. 2025.

