KV Storage - اولین ماژول داخلی وب

فروشندگان مرورگر و کارشناسان عملکرد وب در بخش بهتری از دهه گذشته گفته اند که localStorage کند است و توسعه دهندگان وب باید استفاده از آن را متوقف کنند.

اگر منصف باشیم، افرادی که این را می گویند اشتباه نمی کنند. localStorage یک API همزمان است که رشته اصلی را مسدود می کند و هر زمان که به آن دسترسی پیدا می کنید به طور بالقوه از تعاملی بودن صفحه خود جلوگیری می کنید.

مشکل اینجاست که API localStorage بسیار وسوسه انگیز است و تنها جایگزین ناهمزمان برای localStorage IndexedDB است که (بپذیریم) به دلیل سهولت استفاده یا استقبال از API شناخته شده نیست.

بنابراین توسعه دهندگان با یک انتخاب بین چیزی سخت برای استفاده و چیز بد برای عملکرد روبرو هستند. و در حالی که کتابخانه‌هایی وجود دارند که سادگی localStorage API را ارائه می‌کنند در حالی که در واقع از APIهای ذخیره‌سازی ناهمزمان استفاده می‌کنند، از جمله یکی از این کتابخانه‌ها در برنامه شما هزینه‌ای به اندازه فایل دارد و می‌تواند بودجه عملکرد شما را کاهش دهد.

اما اگر می‌توان عملکرد یک API ذخیره‌سازی ناهمزمان را با سادگی localStorage API بدون پرداخت هزینه اندازه فایل به دست آورد، چه؟

خوب، به زودی ممکن است وجود داشته باشد. کروم در حال آزمایش ویژگی جدیدی است که به عنوان ماژول‌های داخلی شناخته می‌شود و اولین موردی که قصد داریم ارائه کنیم، یک ماژول ذخیره‌سازی کلید/مقدار ناهمزمان به نام KV Storage است.

اما قبل از اینکه به جزئیات ماژول KV Storage بپردازم، اجازه دهید منظورم از ماژول های داخلی را توضیح دهم.

ماژول های داخلی چیست؟

ماژول های داخلی درست مانند ماژول های معمولی جاوا اسکریپت هستند، با این تفاوت که نیازی به دانلود ندارند زیرا با مرورگر ارسال می شوند.

مانند APIهای وب سنتی، ماژول‌های داخلی باید از طریق فرآیند استانداردسازی بگذرند – هر کدام مشخصات خاص خود را دارند که نیاز به بررسی طراحی و نشانه‌های مثبت پشتیبانی هم از سوی توسعه‌دهندگان وب و هم سایر فروشندگان مرورگر قبل از ارسال دارد. (در کروم، ماژول‌های داخلی همان فرآیند راه‌اندازی را دنبال می‌کنند که ما برای پیاده‌سازی و ارسال همه APIهای جدید استفاده می‌کنیم.)

برخلاف API های وب سنتی، ماژول های داخلی در محدوده جهانی قرار نمی گیرند - آنها فقط از طریق واردات در دسترس هستند.

عدم نمایش ماژول های داخلی در سطح جهانی مزایای زیادی دارد: آنها هیچ هزینه ای برای راه اندازی یک زمینه زمان اجرا جدید جاوا اسکریپت اضافه نمی کنند (مثلاً یک برگه، کارگر یا سرویس دهنده جدید)، و هیچ حافظه یا حافظه ای مصرف نمی کنند. CPU مگر اینکه واقعاً وارد شده باشند. علاوه بر این، آنها خطر برخورد نام با سایر متغیرهای تعریف شده در کد شما را ندارند.

برای وارد کردن یک ماژول داخلی، از پیشوند std: و به دنبال آن شناسه ماژول داخلی استفاده می کنید. به عنوان مثال، در مرورگرهای پشتیبانی شده ، می‌توانید ماژول KV Storage را با کد زیر وارد کنید (برای نحوه استفاده از KV Storage polyfill در مرورگرهای پشتیبانی‌نشده به زیر مراجعه کنید):

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

ماژول ذخیره سازی KV

ماژول KV Storage از نظر سادگی شبیه به localStorage API است، اما شکل API آن در واقع به Map جاوا اسکریپت نزدیکتر است. به جای getItem() setItem() و removeItem() دارای get() ، set() و delete() است. همچنین دارای روش‌های نقشه‌مانند دیگری است که برای localStorage در دسترس نیستند، مانند keys() ، values() و entries() ، و مانند Map ، کلیدهای آن نباید رشته‌ای باشند. آنها می توانند هر نوع ساخت یافته-سریالی شونده ای باشند.

برخلاف Map ، همه روش‌های KV Storage یا وعده‌ها یا تکرارکننده‌های غیر همگام را برمی‌گردانند (زیرا نکته اصلی این ماژول این است که برخلاف localStorage همزمان نیست). برای مشاهده کامل API با جزئیات، می توانید به مشخصات مراجعه کنید.

همانطور که ممکن است از مثال کد بالا متوجه شده باشید، ماژول KV Storage دارای یک storage صادرات پیش فرض و یکی با نام export StorageArea است.

storage نمونه‌ای از کلاس StorageArea با نام 'default' است، و این همان چیزی است که توسعه‌دهندگان اغلب در کد برنامه خود از آن استفاده می‌کنند. کلاس StorageArea برای مواردی که به جداسازی اضافی نیاز است (به عنوان مثال یک کتابخانه شخص ثالث که داده ها را ذخیره می کند و می خواهد از تداخل با داده های ذخیره شده از طریق نمونه storage پیش فرض جلوگیری کند) ارائه می شود. داده‌های StorageArea در یک پایگاه داده IndexedDB با نام kv-storage:${name} ذخیره می‌شوند، جایی که 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();

اگر مرورگر از ماژول داخلی پشتیبانی نکند، چه؟

اگر با استفاده از ماژول‌های جاوا اسکریپت بومی در مرورگرها آشنا هستید، احتمالاً می‌دانید که (حداقل تا کنون) وارد کردن هر چیزی غیر از URL باعث ایجاد خطا می‌شود. و std:kv-storage یک URL معتبر نیست.

بنابراین این سوال ایجاد می کند: آیا باید منتظر بمانیم تا همه مرورگرها از ماژول های داخلی پشتیبانی کنند تا بتوانیم از آن در کد خود استفاده کنیم؟ خوشبختانه پاسخ منفی است!

شما واقعاً می‌توانید به محض اینکه حتی یک مرورگر از آنها پشتیبانی می‌کند، به لطف ویژگی دیگری که در حال آزمایش با آن به نام import maps هستیم، از ماژول‌های داخلی استفاده کنید.

وارد کردن نقشه ها

نقشه‌های وارداتی اساساً مکانیزمی هستند که توسط آن توسعه‌دهندگان می‌توانند شناسه‌های مستعار را به یک یا چند شناسه جایگزین وارد کنند.

این قدرتمند است زیرا راهی را به شما می دهد تا (در زمان اجرا) نحوه حل یک شناسه وارداتی خاص را در کل برنامه شما توسط مرورگر تغییر دهید.

در مورد ماژول‌های داخلی، این به شما امکان می‌دهد تا به یک polyfill از ماژول در کد برنامه خود اشاره کنید، اما مرورگری که از ماژول داخلی پشتیبانی می‌کند می‌تواند آن نسخه را بارگیری کند!

در اینجا نحوه اعلام یک نقشه واردات برای انجام این کار با ماژول 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 .

بنابراین هنگامی که مرورگر با یک عبارت import ارجاع به URL ( /path/to/kv-storage-polyfill.mjs ) مواجه می شود، ابتدا سعی می کند std:kv-storage بارگیری کند، و اگر نتوانست، دوباره به بارگذاری باز می گردد. /path/to/kv-storage-polyfill.mjs .

باز هم، جادو در اینجا این است که مرورگر نیازی به پشتیبانی از نقشه‌های وارداتی یا ماژول‌های داخلی برای کارکرد این تکنیک ندارد، زیرا URL ارسال شده به عبارت import، URL برای polyfill است. polyfill در واقع یک بازگشت مجدد نیست، پیش فرض است. ماژول داخلی یک پیشرفت پیشرونده است!

مرورگرهایی که اصلا از ماژول ها پشتیبانی نمی کنند چطور؟

برای استفاده از نقشه های واردات برای بارگذاری مشروط ماژول های داخلی، باید در واقع از دستورهای import استفاده کنید، که همچنین به این معنی است که باید از اسکریپت های ماژول استفاده کنید، یعنی <script type="module"> .

در حال حاضر، بیش از 80 درصد مرورگرها از ماژول‌ها پشتیبانی می‌کنند و برای مرورگرهایی که این کار را انجام نمی‌دهند، می‌توانید از تکنیک ماژول/نومول برای ارائه یک بسته قدیمی استفاده کنید. توجه داشته باشید که هنگام تولید بیلد nomodule خود، باید همه پلی‌فیل‌ها را اضافه کنید، زیرا مطمئناً می‌دانید که مرورگرهایی که از ماژول‌ها پشتیبانی نمی‌کنند، قطعا ماژول‌های داخلی را پشتیبانی نمی‌کنند.

نسخه ی نمایشی ذخیره سازی KV

برای نشان دادن اینکه امکان استفاده از ماژول‌های داخلی در حالی که از مرورگرهای قدیمی‌تر نیز پشتیبانی می‌شود، امکان‌پذیر است، نسخه‌ای را گردآوری کرده‌ام که تمام تکنیک‌های توصیف‌شده در بالا را در خود جای داده و امروزه در همه مرورگرها اجرا می‌شود:

  • مرورگرهایی که از ماژول ها، وارد کردن نقشه ها و ماژول داخلی پشتیبانی می کنند، هیچ کد غیر ضروری را بارگذاری نمی کنند.
  • مرورگرهایی که از ماژول‌ها پشتیبانی می‌کنند و نقشه‌ها را وارد می‌کنند اما ماژول داخلی را پشتیبانی نمی‌کنند ، پلی‌فیل KV Storage را بارگیری می‌کنند (از طریق بارگذار ماژول مرورگر).
  • مرورگرهایی که از ماژول‌ها پشتیبانی می‌کنند اما از نقشه‌های وارداتی پشتیبانی نمی‌کنند، KV Storage polyfill را نیز بارگیری می‌کنند (از طریق بارگذار ماژول مرورگر).
  • مرورگرهایی که اصلاً از ماژول‌ها پشتیبانی نمی‌کنند، KV Storage polyfill را در بسته قدیمی خود دریافت می‌کنند (بارگذاری شده از طریق <script nomodule> ).

نسخه ی نمایشی در Glitch میزبانی می شود، بنابراین می توانید منبع آن را مشاهده کنید . من همچنین توضیح مفصلی در مورد پیاده سازی در README دارم. اگر کنجکاو هستید که ببینید چگونه ساخته شده است، به راحتی نگاهی بیندازید.

برای اینکه عملاً ماژول داخلی داخلی را در عمل ببینید، باید نسخه آزمایشی را در Chrome 74 یا جدیدتر با پرچم ویژگی‌های پلتفرم وب آزمایشی روشن کنید ( chrome://flags/#enable-experimental-web-platform-features ).

می‌توانید تأیید کنید که ماژول داخلی بارگیری می‌شود زیرا اسکریپت polyfill را در پنل منبع در DevTools نمی‌بینید. در عوض، نسخه داخلی ماژول را خواهید دید (واقعیت جالب: می توانید کد منبع ماژول را بررسی کنید یا حتی نقاط شکست را در آن قرار دهید!):

منبع ماژول KV Storage در Chrome DevTools

لطفا به ما بازخورد بدهید

این مقدمه باید به شما مزه آنچه ممکن است با ماژول های داخلی امکان پذیر باشد را به شما می داد. و امیدوارم، شما هیجان زده هستید! ما واقعا دوست داریم که توسعه دهندگان ماژول KV Storage (و همچنین تمام ویژگی های جدید مورد بحث در اینجا) را امتحان کنند و به ما بازخورد بدهند.

در اینجا پیوندهای GitHub وجود دارد که می توانید در مورد هر یک از ویژگی های ذکر شده در این مقاله به ما بازخورد بدهید:

اگر سایت شما در حال حاضر از localStorage استفاده می کند، باید سعی کنید به KV Storage API تغییر دهید تا ببینید آیا تمام نیازهای شما را برآورده می کند یا خیر. و اگر برای آزمایش اولیه KV Storage ثبت نام کنید، می‌توانید این ویژگی‌ها را امروز اجرا کنید. همه کاربران شما باید از عملکرد فضای ذخیره‌سازی بهتر بهره ببرند و کاربران Chrome 74+ نیازی به پرداخت هزینه دانلود اضافی نخواهند داشت.