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

على مدار العقد الماضي، كان مورّدو المتصفّحات وخبراء أداء الويب يردّدون أنّ localStorage بطيء، وأنّ على مطوّري الويب التوقف عن استخدامه.

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

تكمن المشكلة في أنّ واجهة برمجة التطبيقات localStorage API بسيطة جدًا، والبديل الوحيد غير المتزامن لـ localStorage هو IndexedDB، الذي لا يُعرف (لنواجه الأمر) بسهولة استخدامه أو واجهة برمجة التطبيقات الترحيبية.

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

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

حسنًا، قد يكون ذلك قريبًا. يخضع Chrome للتجربة باستخدام ميزة جديدة تُعرف باسم الوحدات المضمّنة، وأول وحدة نخطّط لطرحها هي وحدة تخزين مفاتيح/قيم غير متزامنة تُعرف باسم KV Storage.

ولكن قبل أن أتحدث عن تفاصيل وحدة "تخزين المفاتيح والقيم"، دعني أشرح ما أقصده بـ الوحدات المضمّنة.

ما هي الوحدات المضمّنة؟

الوحدات المضمّنة تشبه وحدات JavaScript العادية، باستثناء أنّه لا يلزم تنزيلها لأنّها تكون مضمّنة في المتصفّح.

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

على عكس واجهات برمجة تطبيقات الويب التقليدية، لا يتم عرض الوحدات المضمّنة في المستوى العميق ، بل تكون متاحة فقط من خلال عمليات الاستيراد.

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

لاستيراد وحدة مضمّنة، استخدِم البادئة std: متبوعة بمعرّف الوحد المضمّنة. على سبيل المثال، في المتصفّحات المتوافقة، يمكنك استيراد وحدة KV Storage باستخدام الرمز البرمجي التالي (اطّلِع أدناه على كيفية استخدام polyfill لـ KV Storage في المتصفّحات غير المتوافقة):

import storage, {StorageArea} from 'std:kv-storage';

وحدة تخزين KV

تتشابه وحدة KV Storage في بساطتها مع واجهة برمجة التطبيقات localStorage API، ولكن يكون شكل واجهة برمجة التطبيقات أقرب إلى Map JavaScript. بدلاً من getItem()، setItem()، وremoveItem()، يتم استخدام get()، set()، وdelete(). تتضمّن هذه الطريقة أيضًا طرقًا أخرى شبيهة بالخرائط غير متاحة localStorage، مثل keys()، values()، entries()، وكما هو الحال مع Map، لا يجب أن تكون مفاتيح هذه الطريقة سلاسل. ويمكن أن تكون أيًا من الأنواع المنظَّمة القابلة للتسلسل.

على عكس Map، تُعرِض جميع طرق KV Storage إما وعودًا أو مكرّرات غير متزامنة (لأنّ النقطة الرئيسية لهذه الوحدة هي أنّها غير متزامنة، على عكس localStorage). للاطّلاع على واجهة برمجة التطبيقات الكاملة بالتفصيل، يمكنك الرجوع إلى المواصفات.

كما قد لاحظت من مثال الرمز أعلاه، تحتوي وحدة KV Storage على عملية تصدير تلقائية واحدة storage وعملية تصدير مُسمّاة واحدة StorageArea.

storage هو مثيل لفئة StorageArea يحمل الاسم 'default'، وهو ما سيستخدمه المطوّرون غالبًا في رمز تطبيقاتهم. يتم توفير فئة StorageArea للحالات التي يكون فيها العزل الإضافي مطلوبًا (مثل مكتبة تابعة لجهة خارجية تخزِّن البيانات وتريد تجنُّب التعارض مع البيانات المخزَّنة من خلال مثيل storage التلقائي). يتم تخزين بيانات StorageArea في قاعدة بيانات IndexedDB باسم kv-storage:${name}، حيث يكون الاسم هو اسم مثيل StorageArea.

في ما يلي مثال على كيفية استخدام وحدة KV Storage في الرمز البرمجي:

import storage from 'std:kv-storage';

const main = async () => {
  const oldPreferences = await storage.get('preferences');

  document.querySelector('form').addEventListener('submit', async () => {
    const newPreferences = Object.assign({}, oldPreferences, {
      // Updated preferences go here...
    });

    await storage.set('preferences', newPreferences);
  });
};

main();

ماذا لو كان المتصفّح لا يتيح استخدام وحدة مضمّنة؟

إذا كنت على دراية باستخدام وحدات JavaScript الأصلية في المتصفّحات، يُرجى العِلم أنّه (حتى الآن على الأقل) قد يؤدي استيراد أي محتوى آخر غير عنوان URL إلى توليد خطأ. وstd:kv-storage ليس عنوان URL صالحًا.

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

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

استيراد الخرائط

خرائط الاستيراد هي في الأساس آلية يمكن للمطوّرين من خلالها إنشاء بديلٍ لمعرّفات الاستيراد باستخدام معرّف واحد أو أكثر بدلاً من المعرّف الأصلي.

وهذا مفيد جدًا لأنّه يمنحك طريقة لتغيير (أثناء التشغيل) كيفية معالجة المتصفّح لمعرّف استيراد معيّن في تطبيقك بأكمله.

في حال الوحدات المضمّنة، يتيح لك ذلك الإشارة إلى polyfill لل الوحدة في رمز تطبيقك، ولكن يمكن لمتصفّح متوافق مع الوحدة المضمّنة carregar esse

في ما يلي كيفية تحديد خريطة استيراد لاستخدامها مع ملف برمجي KV Storage:

<!-- The import map is inlined into your page -->
<script type="importmap">
{
  "imports": {
    "/path/to/kv-storage-polyfill.mjs": [
      "std:kv-storage",
      "/path/to/kv-storage-polyfill.mjs"
    ]
  }
}
</script>

<!-- Then any module scripts with import statements use the above map -->
<script type="module">
  import storage from '/path/to/kv-storage-polyfill.mjs';

  // Use `storage` ...
</script>

النقطة الرئيسية في الرمز أعلاه هي أنّه يتمّ ربط عنوان URL /path/to/kv-storage-polyfill.mjs بموردَين مختلفَين : std:kv-storage ثم عنوان URL الأصلي مرة أخرى، /path/to/kv-storage-polyfill.mjs.

لذلك، عندما يصادف المتصفّح عبارة استيراد تشير إلى عنوان URL (/path/to/kv-storage-polyfill.mjs)، يحاول أولاً تحميل std:kv-storage، وإذا لم يتمكّن من ذلك، يعود إلى تحميل /path/to/kv-storage-polyfill.mjs.

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

ماذا عن المتصفّحات التي لا تتيح استخدام الوحدات على الإطلاق؟

لاستخدام خرائط الاستيراد لتحميل الوحدات المضمّنة بشكل مشروط، عليك استخدام عبارات import فعليًا، ما يعني أيضًا أنّ عليك استخدام نصوص وحدات البرمجة، أي <script type="module">.

في الوقت الحالي، أكثر من% 80 من المتصفّحات تتيح استخدام الوحدات، وبالنسبة إلى المتصفّحات التي لا تتيح ذلك، يمكنك استخدام أسلوب module/nomodule لعرض حِزمة قديمة. يُرجى العلم أنّه عند إنشاء إصدار nomodule، عليك تضمين جميع وحدات الملء لأنّك تعرف بالتأكيد أنّ المتصفّحات التي لا تتوافق مع الوحدات لن تتوافق بالتأكيد مع الوحدات المضمّنة.

عرض توضيحي لـ KV Storage

لتوضيح إمكانية استخدام الوحدات المضمّنة مع مواصلة إتاحة استخدام المتصفّحات القديمة، أنشأت عرضًا توضيحيًا يتضمن جميع التقنيات الموضّحة أعلاه ويمكن تشغيله في جميع المتصفّحات الحالية:

  • لا تحمِّل المتصفّحات التي تتيح استخدام الوحدات و"استيراد الخرائط" والوحدة المضمّنة أي رمز غير مطلوب.
  • إنّ المتصفحات التي تتيح استخدام الوحدات وتصدير الخرائط ولكنّها لا تتيح استخدام الوحدت المدمجة تحمّل العنصر البديل لـ KV Storage (من خلال محمّل الوحدات في المتصفّح).
  • إنّ المتصفحات التي تتيح استخدام الوحدات ولكنّها لا تتيح استيراد الخرائط تحمّل أيضًا KV Storage polyfill (من خلال أداة تحميل الوحدات في المتصفّح).
  • تحصل المتصفحات التي لا تتوافق مع الوحدات على polyfill لـ KV Storage في حِزمة الإصدار القديم (يتم تحميلها من خلال <script nomodule>).

يتم استضافة الإصدار التجريبي على Glitch، لذا يمكنك الاطّلاع على مصدره. لديّ أيضًا شرح مفصّل لعملية التنفيذ فيملف readme.txt README. يمكنك الاطّلاع على هذه الميزة إذا كنت مهتمًا بمعرفة كيفية إنشائها.

للاطّلاع على الوحدة المضمّنة الأصلية أثناء عملها، عليك تحميل الإصدار التمهيدي في Chrome 74 أو إصدار أحدث مع تفعيل ميزة ميزات منصّة الويب التجريبية (chrome://flags/#enable-experimental-web-platform-features).

يمكنك التأكّد من تحميل الوحدة المضمّنة لأنّه لن يظهر النص البرمجي لإضافة polyfill في لوحة المصدر في "أدوات المطوّر"، بل سيظهر إصدار الوحدة المضمّنة (حقيقة ممتعة: يمكنك فحص رمز برمجي مصدر الوحدة أو حتى وضع نقاط توقّف فيها):

مصدر وحدة KV Storage في &quot;أدوات مطوّري البرامج في Chrome&quot;

يُرجى إرسال ملاحظاتك إلينا.

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

في ما يلي روابط GitHub التي يمكنك من خلالها تقديم ملاحظاتك حول كل من الميزات المذكورة في هذه المقالة:

إذا كان موقعك الإلكتروني يستخدم حاليًا localStorage، ننصحك بتجربة KV Storage API لمعرفة ما إذا كانت تلبي جميع احتياجاتك. وإذا اشتركت في فترة تجريبية لإصدار KV Storage الأصلي، يمكنك نشر هذه الميزات اليوم. من المفترض أن يستفيد جميع المستخدمين من أداء تخزين أفضل، ولن يضطر مستخدمو الإصدار 74 من Chrome والإصدارات الأحدث إلى دفع أي تكلفة إضافية مقابل تنزيل التطبيقات.