فروشندگان مرورگر و کارشناسان عملکرد وب در بخش بهتری از دهه گذشته گفته اند که 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 (و همچنین تمام ویژگی های جدید مورد بحث در اینجا) را امتحان کنند و به ما بازخورد بدهند.
در اینجا پیوندهای GitHub وجود دارد که می توانید در مورد هر یک از ویژگی های ذکر شده در این مقاله به ما بازخورد بدهید:
اگر سایت شما در حال حاضر از localStorage
استفاده می کند، باید سعی کنید به KV Storage API تغییر دهید تا ببینید آیا تمام نیازهای شما را برآورده می کند یا خیر. و اگر برای آزمایش اولیه KV Storage ثبت نام کنید، میتوانید این ویژگیها را امروز اجرا کنید. همه کاربران شما باید از عملکرد فضای ذخیرهسازی بهتر بهره ببرند و کاربران Chrome 74+ نیازی به پرداخت هزینه دانلود اضافی نخواهند داشت.