สรุปสั้นๆ
Chrome เวอร์ชัน 61 และเบราว์เซอร์อื่นๆ ที่จะตามมาจะแสดงพื้นที่เก็บข้อมูลโดยประมาณที่เว็บแอปใช้อยู่และพื้นที่เก็บข้อมูลที่เหลืออยู่ผ่านช่องทางต่อไปนี้
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate().then(({usage, quota}) => {
console.log(`Using ${usage} out of ${quota} bytes.`);
});
}
เว็บแอปและพื้นที่เก็บข้อมูลสมัยใหม่
เมื่อพิจารณาถึงความต้องการพื้นที่เก็บข้อมูลของเว็บแอปพลิเคชันสมัยใหม่ คุณควรแบ่งสิ่งที่จัดเก็บออกเป็น 2 หมวดหมู่ ได้แก่ ข้อมูลหลักที่จำเป็นในการโหลดเว็บแอปพลิเคชันและข้อมูลที่จําเป็นสําหรับการโต้ตอบของผู้ใช้ที่มีความหมายเมื่อโหลดแอปพลิเคชันแล้ว
ข้อมูลประเภทแรกคือข้อมูลที่จำเป็นในการโหลดเว็บแอป ซึ่งประกอบด้วย HTML, JavaScript, CSS และอาจรวมถึงรูปภาพบางรายการ Service Worker พร้อมกับ Cache Storage API จะจัดหาโครงสร้างพื้นฐานที่จําเป็นสําหรับการบันทึกทรัพยากรหลักเหล่านั้น จากนั้นนําไปใช้ภายหลังเพื่อโหลดเว็บแอปอย่างรวดเร็ว โดยวิธีที่ดีที่สุดคือข้ามเครือข่ายไปเลย
(เครื่องมือที่ผสานรวมกับกระบวนการบิลด์ของเว็บแอป เช่น ไลบรารี Workbox เวอร์ชันใหม่หรือ sw-precache
เวอร์ชันเก่า สามารถทำให้กระบวนการจัดเก็บ อัปเดต และใช้ข้อมูลประเภทนี้เป็นแบบอัตโนมัติได้ทั้งหมด)
แล้วข้อมูลประเภทอื่นๆ ล่ะ ทรัพยากรเหล่านี้ไม่จำเป็นต่อการโหลดเว็บแอป แต่อาจมีความสำคัญอย่างยิ่งต่อประสบการณ์โดยรวมของผู้ใช้ เช่น หากคุณเขียนเว็บแอปสำหรับแก้ไขรูปภาพ คุณอาจต้องการบันทึกสำเนารูปภาพในเครื่องอย่างน้อย 1 รายการเพื่อให้ผู้ใช้สลับระหว่างการแก้ไขและการเลิกทำงานได้ หรือหากคุณกำลังพัฒนาประสบการณ์การเล่นสื่อแบบออฟไลน์ การบันทึกไฟล์เสียงหรือวิดีโอไว้ในเครื่องจะเป็นฟีเจอร์สําคัญ เว็บแอปทุกรายการที่ปรับเปลี่ยนในแบบของคุณได้จะต้องบันทึกข้อมูลสถานะบางประเภท คุณทราบได้อย่างไรว่าพื้นที่เก็บข้อมูลรันไทม์ประเภทนี้มีเหลืออยู่เท่าใด และจะเกิดอะไรขึ้นเมื่อพื้นที่เก็บข้อมูลเต็ม
ที่ผ่านมา: window.webkitStorageInfo
และ navigator.webkitTemporaryStorage
ที่ผ่านมาเบราว์เซอร์รองรับการตรวจสอบตัวเองประเภทนี้ผ่านอินเทอร์เฟซที่มีคำนำหน้า เช่น window.webkitStorageInfo
ที่เก่ามาก (และเลิกใช้งานแล้ว) และnavigator.webkitTemporaryStorage
ที่เก่าไม่มากนักแต่ยังไม่เป็นมาตรฐาน
แม้ว่าอินเทอร์เฟซเหล่านี้จะให้ข้อมูลที่เป็นประโยชน์ แต่ก็ไม่ได้เป็นมาตรฐานเว็บในอนาคต
ด้วยเหตุนี้ มาตรฐานพื้นที่เก็บข้อมูล WHATWG จึงเข้ามามีบทบาท
อนาคต: navigator.storage
เราได้เพิ่ม API ที่มีประโยชน์ 2 รายการลงในStorageManager
อินเทอร์เฟซซึ่งแสดงในเบราว์เซอร์เป็น navigator.storage
เพื่อเป็นส่วนหนึ่งของการทำงานอย่างต่อเนื่องเกี่ยวกับ Storage Living Standard
เช่นเดียวกับ Web API ใหม่ๆ อื่นๆ อีกมากมาย navigator.storage
ใช้ได้เฉพาะในต้นทางที่ปลอดภัย (แสดงผ่าน HTTPS หรือ localhost)
เมื่อปีที่แล้ว เราได้เปิดตัววิธี navigator.storage.persist()
ซึ่งช่วยให้เว็บแอปพลิเคชันสามารถส่งคำขอยกเว้นพื้นที่เก็บข้อมูลจากการล้างข้อมูลอัตโนมัติ
ตอนนี้มีวิธีการ navigator.storage.estimate()
เข้ามาร่วมด้วย ซึ่งทำหน้าที่เป็น navigator.webkitTemporaryStorage.queryUsageAndQuota()
เวอร์ชันสมัยใหม่
estimate()
จะแสดงข้อมูลที่คล้ายกัน แต่แสดงอินเทอร์เฟซตามสัญญา ซึ่งสอดคล้องกับ API แบบแอซิงโครนัสสมัยใหม่อื่นๆ พรมิสที่ estimate()
แสดงผลจะแสดงผลด้วยออบเจ็กต์ที่มีพร็อพเพอร์ตี้ 2 รายการ ได้แก่ usage
ซึ่งแสดงจํานวนไบต์ที่ใช้อยู่ในปัจจุบัน และ quota
ซึ่งแสดงจํานวนไบต์สูงสุดที่ต้นทางปัจจุบันจัดเก็บได้
(เช่นเดียวกับทุกอย่างที่เกี่ยวข้องกับพื้นที่เก็บข้อมูล ระบบจะใช้โควต้ากับทั้งต้นทาง)
หากเว็บแอปพลิเคชันพยายามจัดเก็บข้อมูลโดยใช้ IndexedDB หรือ Cache Storage API ตัวอย่างเช่น ข้อมูลที่มีขนาดใหญ่พอที่จะทำให้ต้นทางหนึ่งๆ มีโควต้าเกินจากที่มีอยู่ คำขอจะดำเนินการไม่สำเร็จพร้อมข้อยกเว้น QuotaExceededError
พื้นที่เก็บข้อมูลโดยประมาณที่ใช้งานอยู่
วิธีที่แน่นอนที่คุณใช้ estimate()
จะขึ้นอยู่กับประเภทข้อมูลที่แอปของคุณต้องจัดเก็บ เช่น คุณสามารถอัปเดตการควบคุมในอินเทอร์เฟซเพื่อให้ผู้ใช้ทราบปริมาณพื้นที่ที่ใช้หลังจากการดำเนินการกับพื้นที่เก็บข้อมูลแต่ละรายการเสร็จสมบูรณ์
จากนั้นคุณควรจัดเตรียมอินเทอร์เฟซที่ช่วยให้ผู้ใช้ล้างข้อมูลที่ไม่จำเป็นออกด้วยตนเองได้ คุณอาจเขียนโค้ดประมาณนี้
// For a primer on async/await, see
// https://developers.google.com/web/fundamentals/getting-started/primers/async-functions
async function storeDataAndUpdateUI(dataUrl) {
// Pro-tip: The Cache Storage API is available outside of service workers!
// See https://googlechrome.github.io/samples/service-worker/window-caches/
const cache = await caches.open('data-cache');
await cache.add(dataUrl);
if ('storage' in navigator && 'estimate' in navigator.storage) {
const {usage, quota} = await navigator.storage.estimate();
const percentUsed = Math.round(usage / quota * 100);
const usageInMib = Math.round(usage / (1024 * 1024));
const quotaInMib = Math.round(quota / (1024 * 1024));
const details = `${usageInMib} out of ${quotaInMib} MiB used (${percentUsed}%)`;
// This assumes there's a <span id="storageEstimate"> or similar on the page.
document.querySelector('#storageEstimate').innerText = details;
}
}
ค่าประมาณมีความแม่นยำเพียงใด
โปรดทราบว่าข้อมูลที่ได้จากฟังก์ชันเป็นเพียงพื้นที่โดยประมาณที่ต้นทางใช้อยู่ อยู่ตรงนั้นในชื่อฟังก์ชัน ค่า usage
และ quota
ไม่ได้มีไว้เพื่อให้คงที่ เราจึงขอแนะนำให้คุณพิจารณาสิ่งต่อไปนี้
usage
แสดงจํานวนไบต์ที่แหล่งที่มาหนึ่งๆ ใช้จริงสําหรับข้อมูลแหล่งที่มาเดียวกัน ซึ่งอาจได้รับผลกระทบจากเทคนิคการบีบอัดภายใน บล็อกการจัดสรรขนาดคงที่ที่อาจมีพื้นที่ว่างที่ไม่ได้ใช้ และการมีระเบียน"Tombstone" ที่อาจสร้างขึ้นชั่วคราวหลังจากการลบ เพื่อป้องกันไม่ให้ข้อมูลขนาดที่แน่นอนรั่วไหล ทรัพยากรแบบทึบแสงข้ามแหล่งที่มาซึ่งบันทึกไว้ในเครื่องอาจเพิ่มไบต์การถ่วงลงในค่าusage
โดยรวมquota
แสดงพื้นที่ที่จองไว้สําหรับต้นทางหนึ่งๆ ในปัจจุบัน ค่านี้ขึ้นอยู่กับปัจจัยคงที่บางประการ เช่น ขนาดพื้นที่เก็บข้อมูลโดยรวม รวมถึงปัจจัยที่อาจผันผวนจำนวนหนึ่ง ซึ่งรวมถึงปริมาณพื้นที่เก็บข้อมูลที่ไม่ได้ใช้ในปัจจุบัน ดังนั้นเมื่อแอปพลิเคชันอื่นๆ ในอุปกรณ์เขียนหรือลบข้อมูล ปริมาณพื้นที่เบราว์เซอร์จะจัดสรรให้กับต้นทางของเว็บแอปมีแนวโน้มที่จะเปลี่ยนแปลง
ปัจจุบัน: การตรวจหาฟีเจอร์และการแสดงผลสำรอง
estimate()
จะเปิดใช้โดยค่าเริ่มต้นตั้งแต่ Chrome เวอร์ชัน 61 เป็นต้นไป Firefox กำลังทดลองใช้ navigator.storage
แต่ในเดือนสิงหาคม 2017 ไม่ได้เปิดใช้โดยค่าเริ่มต้น คุณต้องเปิดใช้ค่ากําหนด dom.storageManager.enabled
เพื่อทดสอบ
เมื่อต้องทํางานกับฟังก์ชันที่เบราว์เซอร์บางรุ่นยังไม่รองรับ คุณต้องใช้การตรวจหาฟีเจอร์ คุณสามารถรวมการตรวจหาฟีเจอร์เข้ากับ Wrapper ตามสัญญาไว้ด้านบนของnavigator.webkitTemporaryStorage
วิธีเก่าๆ เพื่อให้อินเทอร์เฟซสอดคล้องกันตามแนวทางต่อไปนี้
function storageEstimateWrapper() {
if ('storage' in navigator && 'estimate' in navigator.storage) {
// We've got the real thing! Return its response.
return navigator.storage.estimate();
}
if ('webkitTemporaryStorage' in navigator &&
'queryUsageAndQuota' in navigator.webkitTemporaryStorage) {
// Return a promise-based wrapper that will follow the expected interface.
return new Promise(function(resolve, reject) {
navigator.webkitTemporaryStorage.queryUsageAndQuota(
function(usage, quota) {resolve({usage: usage, quota: quota})},
reject
);
});
}
// If we can't estimate the values, return a Promise that resolves with NaN.
return Promise.resolve({usage: NaN, quota: NaN});
}