แนวทางปฏิบัติแนะนำในการเก็บสถานะแอปพลิเคชันถาวรด้วย IndexedDB

ดูแนวทางปฏิบัติแนะนำสำหรับการซิงค์สถานะแอปพลิเคชันระหว่าง IndexedDB กับไลบรารีการจัดการสถานะที่ได้รับความนิยม

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

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

อย่างไรก็ตาม เมื่อใช้ IndexedDB มีข้อสําคัญหลายประการที่ควรพิจารณา ซึ่งนักพัฒนาซอฟต์แวร์มือใหม่อาจไม่เข้าใจในทันที เอกสารนี้จะตอบคําถามที่พบบ่อยและกล่าวถึงสิ่งสําคัญบางประการที่ควรคํานึงถึงเมื่อเก็บสถานะแอปพลิเคชันไว้ใน IndexedDB

ทำให้แอปคาดการณ์ได้

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

การเขียนไปยังพื้นที่เก็บข้อมูลอาจไม่สำเร็จ

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

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

ผู้ใช้อาจแก้ไขหรือลบข้อมูลที่จัดเก็บไว้

ซึ่งแตกต่างจากฐานข้อมูลฝั่งเซิร์ฟเวอร์ที่คุณสามารถจํากัดการเข้าถึงที่ไม่ได้รับอนุญาตได้ ส่วนฐานข้อมูลฝั่งไคลเอ็นต์จะเข้าถึงได้ผ่านส่วนขยายเบราว์เซอร์และเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์ และผู้ใช้สามารถล้างข้อมูลดังกล่าวได้

แม้ว่าผู้ใช้จะไม่ค่อยแก้ไขข้อมูลที่จัดเก็บไว้ในเครื่อง แต่ผู้ใช้มักจะล้างข้อมูลดังกล่าว แอปพลิเคชันต้องจัดการทั้ง 2 กรณีนี้โดยไม่มีข้อผิดพลาด

ข้อมูลที่จัดเก็บไว้อาจล้าสมัย

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

IndexedDB รองรับเวอร์ชันสคีมาและการอัปเกรดโดยใช้เมธอด IDBOpenDBRequest.onupgradeneeded() ในตัว แต่คุณยังคงต้องเขียนโค้ดการอัปเกรดในลักษณะที่จัดการผู้ใช้ที่มาจากเวอร์ชันก่อนหน้าได้ (รวมถึงเวอร์ชันที่มีข้อบกพร่อง)

การทดสอบหน่วยจะมีประโยชน์มากในกรณีนี้ เนื่องจากบ่อยครั้งที่การทดสอบเส้นทางและกรณีการอัปเกรดที่เป็นไปได้ทั้งหมดด้วยตนเองนั้นไม่สามารถทำได้

รักษาประสิทธิภาพของแอป

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

โดยทั่วไปแล้ว การอ่านและเขียนลงใน IndexedDB ไม่ควรมีขนาดใหญ่เกินกว่าที่จําเป็นสําหรับข้อมูลที่เข้าถึง

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

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

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

คุณควรแบ่งต้นไม้สถานะออกเป็นระเบียนแต่ละรายการและอัปเดตเฉพาะระเบียนที่เปลี่ยนแปลงจริงๆ แทนที่จะจัดเก็บต้นไม้สถานะทั้งหมดไว้ในระเบียนเดียว

เช่นเดียวกับแนวทางปฏิบัติแนะนำส่วนใหญ่ แนวทางนี้ไม่ใช่กฎที่ต้องปฏิบัติตามทั้งหมด ในกรณีที่ไม่สามารถแยกออบเจ็กต์สถานะออกเป็นส่วนๆ และเขียนชุดการเปลี่ยนแปลงเพียงชุดเดียว การแยกข้อมูลออกเป็นต้นไม้ย่อยๆ และเขียนเฉพาะข้อมูลเหล่านั้นยังคงดีกว่าการเขียนต้นไม้สถานะทั้งหมดเสมอ การปรับปรุงเล็กๆ น้อยๆ ก็ยังดีกว่าไม่ปรับปรุงเลย

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

สรุป

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

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

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