พื้นที่เก็บข้อมูล KV - โมดูลในตัวแรกของเว็บ

ผู้ให้บริการเบราว์เซอร์และผู้เชี่ยวชาญด้านประสิทธิภาพเว็บได้แจ้งให้ทราบถึงช่วงที่ดีขึ้นในช่วง 10 ปีที่ผ่านมาว่า localStorage ทำงานช้า และนักพัฒนาเว็บควรหยุดใช้บริการดังกล่าว

อันที่จริงคนที่บอกว่าเรื่องนี้ไม่ใช่เรื่องผิด localStorage คือ API แบบซิงโครนัสที่บล็อกเทรดหลัก และเมื่อใดก็ตามที่คุณเข้าถึง API ดังกล่าว อาจทำให้หน้าเว็บไม่โต้ตอบ

ปัญหาอยู่ที่ API ของ localStorage นั้นดูง่ายมากๆ และทางเลือกเพียงแบบเดียวแทน localStorage ก็คือ IndexedDB ซึ่ง (ขออภัยด้วย) ไม่รู้ว่า API นี้ใช้งานง่ายหรือน่าใช้

นักพัฒนาแอปจึงมีทางเลือกระหว่างบางสิ่งที่ใช้งานยากและ สิ่งที่แย่สำหรับประสิทธิภาพ และแม้ว่าจะมีไลบรารีที่ให้ความเรียบง่ายของ localStorage API ในขณะที่ใช้ API พื้นที่เก็บข้อมูลแบบไม่พร้อมกันในการทำงานจริง ก็ยังมีไลบรารีตัวใดตัวหนึ่งที่อยู่ในแอปของคุณมีค่าใช้จ่ายขนาดไฟล์และสามารถกินงบประมาณในงบประมาณด้านประสิทธิภาพได้

แต่จะเกิดอะไรขึ้นหากเราจะรับประสิทธิภาพของ API พื้นที่เก็บข้อมูลแบบไม่พร้อมกันกับ localStorage API โดยไม่ต้องเสียค่าใช้จ่ายเกี่ยวกับขนาดไฟล์

อาจจะมีในเร็วๆ นี้ Chrome กำลังทดสอบฟีเจอร์ใหม่ที่เรียกว่าโมดูลในตัว และฟีเจอร์แรกที่เราวางแผนจะจัดส่งคือโมดูลพื้นที่เก็บข้อมูลคีย์/ค่าแบบไม่พร้อมกันที่เรียกว่าพื้นที่เก็บข้อมูล KV

แต่ก่อนที่จะลงรายละเอียดของโมดูลพื้นที่เก็บข้อมูล KV เราขออธิบายความหมายของโมดูลในตัวก่อน

โมดูลในตัวคืออะไร

โมดูลในตัวจะเหมือนกับโมดูล JavaScript ทั่วไป ยกเว้นว่าไม่จำเป็นต้องดาวน์โหลดเพราะจะมาพร้อมกับเบราว์เซอร์

โมดูลในตัวต้องผ่านกระบวนการกำหนดมาตรฐาน เช่นเดียวกับ API ของเว็บแบบดั้งเดิม ซึ่งแต่ละโมดูลจะมีข้อกำหนดเฉพาะที่ต้องมีการตรวจสอบการออกแบบ และมีสัญญาณที่ดีว่าได้รับการสนับสนุนจากทั้งนักพัฒนาเว็บและผู้ให้บริการเบราว์เซอร์รายอื่นๆ ก่อนที่จะจัดส่งได้ (ใน Chrome โมดูลในตัวจะเป็นไปตามกระบวนการเปิดตัวเดียวกันกับที่เราใช้เพื่อติดตั้งใช้งานและจัดส่ง API ใหม่ทั้งหมด)

โมดูลในตัวต่างจาก API ของเว็บแบบดั้งเดิมตรงที่จะไม่แสดงในขอบเขตทั่วโลก โดยจะใช้ได้เฉพาะผ่านการนำเข้าเท่านั้น

การไม่แสดงโมดูลในตัวทั่วโลกมีข้อดีมากมาย เพราะไม่เพิ่มโอเวอร์เฮดในการเริ่มบริบทรันไทม์ของ JavaScript ใหม่ (เช่น แท็บใหม่ ผู้ปฏิบัติงาน หรือโปรแกรมทำงานของบริการ) และไม่ต้องใช้หน่วยความจำหรือ CPU เลย เว้นแต่จะนำเข้ามาจริงๆ นอกจากนี้ พารามิเตอร์เหล่านี้จะไม่เสี่ยงต่อการตั้งชื่อชนกับตัวแปรอื่นๆ ที่กำหนดไว้ในโค้ดของคุณ

หากต้องการนำเข้าโมดูลในตัว ให้ใช้คำนำหน้า std: ตามด้วยตัวระบุของโมดูลในตัว เช่น ในเบราว์เซอร์ที่รองรับ คุณจะนำเข้าโมดูลพื้นที่เก็บข้อมูล KV ได้ด้วยโค้ดต่อไปนี้ (ดูวิธีใช้โพลีฟิลล์ของพื้นที่เก็บข้อมูล KV ในเบราว์เซอร์ที่ไม่รองรับด้านล่าง)

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

โมดูล KV Storage

โมดูล KV Storage มีความเรียบง่ายคล้ายกับ localStorage API แต่รูปร่าง API ของโมดูลนี้ใกล้เคียงกับ JavaScript Map มากกว่า แทนที่จะเป็น getItem(), setItem() และ removeItem() แต่มี get() set() และ delete() และยังมีเมธอดที่เหมือนกับแผนที่อื่นๆ ไม่พร้อมใช้งานสำหรับ localStorage เช่น keys(), values() และ entries() และเช่น Map คีย์ของ localStorage ไม่จำเป็นต้องเป็นสตริง ซึ่งจะเป็นประเภทใดก็ตามที่สร้างเป็นอนุกรมแบบโครงสร้างก็ได้

เมธอดพื้นที่เก็บข้อมูล KV ทั้งหมดจะแสดงผล คำสัญญา หรือตัวซ้ำแบบไม่พร้อมกัน (เนื่องจากประเด็นหลักของโมดูลนี้คือไม่ใช่แบบซิงโครนัส ซึ่งต่างจาก localStorage) หากต้องการดู API แบบเต็มโดยละเอียด ให้ดูข้อกำหนดMap

คุณอาจสังเกตเห็นจากตัวอย่างโค้ดด้านบนว่าโมดูลพื้นที่เก็บข้อมูล KV มีการส่งออกเริ่มต้น 1 รายการ storage และการส่งออกชื่อ StorageArea

storage เป็นอินสแตนซ์ของคลาส StorageArea ที่ใช้ชื่อ 'default' และเป็นสิ่งที่นักพัฒนาซอฟต์แวร์จะใช้บ่อยที่สุดในโค้ดแอปพลิเคชันของตน ระบบจะจัดเตรียมคลาส StorageArea ไว้ในกรณีที่จำเป็นต้องแยกเพิ่มเติม (เช่น ไลบรารีของบุคคลที่สามซึ่งจัดเก็บข้อมูลและต้องการหลีกเลี่ยงความขัดแย้งกับข้อมูลที่จัดเก็บผ่านอินสแตนซ์ storage เริ่มต้น) ข้อมูล StorageArea จะเก็บอยู่ในฐานข้อมูล IndexedDB ที่ใช้ชื่อ kv-storage:${name} โดยที่ชื่อคือชื่อของอินสแตนซ์ StorageArea

ต่อไปนี้คือตัวอย่างวิธีใช้โมดูลพื้นที่เก็บข้อมูล KV ในโค้ดของคุณ

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 ที่ถูกต้อง

จึงเกิดคำถามว่าเราต้องรอจนกว่าเบราว์เซอร์ทุกตัวจะรองรับโมดูลในตัวก่อนที่จะใช้ในโค้ดได้ใช่ไหม โชคดีที่คำตอบคือไม่

คุณสามารถใช้โมดูลในตัวได้ทันทีเมื่อมีเบราว์เซอร์หนึ่งรองรับ ด้วยความช่วยเหลือจากอีกคุณลักษณะหนึ่งที่เรากำลังทดลองที่เรียกว่าการนำเข้าแผนที่

นำเข้าแผนที่

แผนที่นำเข้าเป็นกลไกที่นักพัฒนาซอฟต์แวร์ใช้นำเข้าตัวระบุแทนการนำเข้าไปยังตัวระบุทางเลือกอย่างน้อย 1 ตัวได้

วิธีนี้มีประสิทธิภาพเนื่องจากช่วยให้คุณเปลี่ยนแปลง (ขณะรันไทม์) ว่าเบราว์เซอร์แก้ไขตัวระบุการนำเข้าหนึ่งๆ อย่างไรในแอปพลิเคชันทั้งหมด

ในกรณีของโมดูลในตัว สิ่งนี้จะช่วยให้คุณอ้างอิง Polyfill ของโมดูลในโค้ดแอปพลิเคชันของคุณได้ แต่เบราว์เซอร์ที่รองรับโมดูลในตัวสามารถโหลดเวอร์ชันนั้นแทนได้

วิธีประกาศแผนที่การนำเข้าเพื่อให้ใช้กับโมดูลพื้นที่เก็บข้อมูล KV ได้มีดังนี้

<!-- 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 กำลังแมปกับทรัพยากร 2 รายการที่แตกต่างกัน ได้แก่ 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% รองรับโมดูล และสำหรับเบราว์เซอร์ที่ไม่รองรับ คุณสามารถใช้เทคนิคโมดูล/ไม่มีโมดูลเพื่อแสดงแพ็กเกจเดิมได้ โปรดทราบว่าเมื่อสร้างบิลด์ nomodule คุณจะต้องรวม Polyfill ทั้งหมด เนื่องจากคุณรู้แล้วว่าเบราว์เซอร์ที่ไม่รองรับโมดูลจะไม่รองรับโมดูลในตัวอย่างแน่นอน

การสาธิตพื้นที่เก็บข้อมูล KV

เพื่อให้เห็นภาพว่าสามารถใช้โมดูลในตัวได้ขณะที่ยังคงรองรับเบราว์เซอร์รุ่นเก่าๆ อยู่ ผมจึงได้จัดทำการสาธิตที่รวมเทคนิคทั้งหมดที่อธิบายไว้ข้างต้นนี้และใช้งานในเบราว์เซอร์ทุกชนิดในปัจจุบัน ดังนี้

  • เบราว์เซอร์ที่สนับสนุนโมดูล การนำเข้าแผนที่ และโมดูลในตัวจะไม่โหลดโค้ดใดๆ ที่ไม่จำเป็น
  • เบราว์เซอร์ที่รองรับโมดูลและนำเข้าแผนที่แต่ไม่รองรับโมดูลในตัวจะโหลด KV Storage Polyfill (ผ่านตัวโหลดโมดูลของเบราว์เซอร์)
  • เบราว์เซอร์ที่รองรับโมดูลแต่ไม่รองรับการนำเข้าแผนที่จะโหลด Polyfill ของ KV Storage ด้วย (ผ่านตัวโหลดโมดูลของเบราว์เซอร์)
  • เบราว์เซอร์ที่ไม่รองรับโมดูลเลยจะได้รับ KV Storage Polyfill ในแพ็กเกจเดิม (โหลดผ่าน <script nomodule>)

การสาธิตโฮสต์อยู่บน Glitch คุณจึงดูแหล่งที่มาได้ เรามีคำอธิบายโดยละเอียดเกี่ยวกับการใช้งานใน README ลองดูได้เลยว่าสร้างขึ้นอย่างไร

หากต้องการดูการทำงานของโมดูลในตัวแบบเนทีฟ คุณต้องโหลดเดโมใน Chrome 74 ขึ้นไปโดยเปิดใช้แฟล็กฟีเจอร์แพลตฟอร์มเว็บแบบทดลอง (chrome://flags/#enable-experimental-web-platform-features)

คุณตรวจสอบได้ว่าโมดูลในตัวกำลังโหลดอยู่เนื่องจากคุณจะไม่เห็นสคริปต์ Polyfill ในแผงแหล่งที่มาในเครื่องมือสำหรับนักพัฒนาเว็บ แต่จะเห็นเวอร์ชันโมดูลในตัวแทน (อันที่จริงคุณสามารถตรวจสอบซอร์สโค้ดของโมดูลหรือแม้แต่ใส่เบรกพอยท์ไว้ในก็ได้)

แหล่งที่มาของโมดูลพื้นที่เก็บข้อมูล KV ในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

โปรดส่งความคิดเห็นถึงเรา

บทแนะนำนี้น่าจะทำให้คุณได้ทราบถึงสิ่งที่เป็นไปได้เมื่อใช้โมดูลในตัว หวังว่าคุณจะตื่นเต้นนะ เราอยากให้นักพัฒนาซอฟต์แวร์ลองใช้โมดูลพื้นที่เก็บข้อมูล KV (รวมถึงฟีเจอร์ใหม่ทั้งหมดที่กล่าวถึงที่นี่) และส่งความคิดเห็นถึงเรา

นี่คือลิงก์ GitHub ที่คุณสามารถแสดงความคิดเห็นเกี่ยวกับแต่ละฟีเจอร์ที่กล่าวถึงในบทความนี้ได้

หากเว็บไซต์ของคุณใช้ localStorage อยู่ในขณะนี้ คุณควรลองเปลี่ยนไปใช้ KV Storage API เพื่อดูว่าบริการเป็นไปตามความต้องการของคุณไหม และหากลงชื่อสมัครทดลองใช้พื้นที่เก็บข้อมูล KV จากต้นทาง คุณก็ใช้งานฟีเจอร์เหล่านี้ได้เลย ผู้ใช้ทุกคนจะได้รับประโยชน์จากการใช้พื้นที่เก็บข้อมูลที่ดีขึ้น และผู้ใช้ Chrome 74 ขึ้นไปก็ไม่ต้องเสียค่าใช้จ่ายในการดาวน์โหลดเพิ่มเติม