ผู้ให้บริการเบราว์เซอร์และผู้เชี่ยวชาญด้านประสิทธิภาพเว็บได้แจ้งให้ทราบถึงช่วงที่ดีขึ้นในช่วง 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 (รวมถึงฟีเจอร์ใหม่ทั้งหมดที่กล่าวถึงที่นี่) และส่งความคิดเห็นถึงเรา
นี่คือลิงก์ GitHub ที่คุณสามารถแสดงความคิดเห็นเกี่ยวกับแต่ละฟีเจอร์ที่กล่าวถึงในบทความนี้ได้
หากเว็บไซต์ของคุณใช้ localStorage
อยู่ในขณะนี้ คุณควรลองเปลี่ยนไปใช้ KV Storage API เพื่อดูว่าบริการเป็นไปตามความต้องการของคุณไหม และหากลงชื่อสมัครทดลองใช้พื้นที่เก็บข้อมูล KV จากต้นทาง คุณก็ใช้งานฟีเจอร์เหล่านี้ได้เลย ผู้ใช้ทุกคนจะได้รับประโยชน์จากการใช้พื้นที่เก็บข้อมูลที่ดีขึ้น และผู้ใช้ Chrome 74 ขึ้นไปก็ไม่ต้องเสียค่าใช้จ่ายในการดาวน์โหลดเพิ่มเติม