वेब के लिए स्टोरेज

ब्राउज़र में डेटा सेव करने के कई विकल्प हैं. आपकी ज़रूरतों के हिसाब से कौनसा विकल्प सबसे अच्छा है?

कभी-कभी इंटरनेट कनेक्शन ठीक से काम नहीं करता या काम ही नहीं करता. इसलिए, प्रगतिशील वेब ऐप्लिकेशन में ऑफ़लाइन सहायता और भरोसेमंद परफ़ॉर्मेंस की सुविधाएं आम तौर पर उपलब्ध होती हैं. बेहतर वायरलेस नेटवर्क वाले इलाकों में भी, कैश मेमोरी और स्टोरेज की अन्य तकनीकों का सही तरीके से इस्तेमाल करके, उपयोगकर्ता अनुभव को काफ़ी बेहतर बनाया जा सकता है. अपने स्टैटिक ऐप्लिकेशन रिसॉर्स (एचटीएमएल, JavaScript, सीएसएस, इमेज वगैरह) और डेटा (उपयोगकर्ता का डेटा, खबरों के लेख वगैरह) को कैश मेमोरी में सेव करने के कई तरीके हैं. लेकिन सबसे अच्छा तरीका क्या है? कितनी जानकारी सेव की जा सकती है? इसे हटाए जाने से कैसे रोका जा सकता है?

मुझे किसका इस्तेमाल करना चाहिए?

संसाधनों को सेव करने के लिए, यहां एक सामान्य सुझाव दिया गया है:

  • अपने ऐप्लिकेशन को लोड करने के लिए ज़रूरी नेटवर्क संसाधनों के लिए, Cache Storage API का इस्तेमाल करें. यह सर्विस वर्कर का हिस्सा है.
  • फ़ाइल-आधारित कॉन्टेंट के लिए, Origin Private File System (OPFS) का इस्तेमाल करें.
  • अन्य डेटा के लिए, IndexedDB का इस्तेमाल करें. साथ ही, promises wrapper का इस्तेमाल करें.

IndexedDB, OPFS, और Cache Storage API, सभी आधुनिक ब्राउज़र पर काम करते हैं. ये असाइनमेंट एसिंक्रोनस होते हैं और ये मुख्य थ्रेड को ब्लॉक नहीं करते. हालांकि, OPFS का एक सिंक्रोनस वैरिएंट भी होता है, जो सिर्फ़ वेब वर्कर में उपलब्ध होता है. इन्हें window ऑब्जेक्ट, वेब वर्कर्स, और सेवा वर्कर्स से ऐक्सेस किया जा सकता है. इससे, इन्हें अपने कोड में कहीं भी इस्तेमाल किया जा सकता है.

स्टोरेज के दूसरे तरीकों के बारे में क्या?

ब्राउज़र में स्टोरेज के कई अन्य तरीके उपलब्ध हैं, लेकिन उनका इस्तेमाल सीमित तौर पर किया जा सकता है. साथ ही, इनकी वजह से परफ़ॉर्मेंस से जुड़ी गंभीर समस्याएं हो सकती हैं.

SessionStorage, टैब के हिसाब से होता है और इसका दायरा, टैब के लाइफ़टाइम तक सीमित होता है. यह सेशन से जुड़ी कम जानकारी को सेव करने के लिए काम का हो सकता है. उदाहरण के लिए, IndexedDB की कोई कुंजी. इसका इस्तेमाल सावधानी से किया जाना चाहिए, क्योंकि यह सिंक करता है और मुख्य थ्रेड को ब्लॉक कर देगा. इसकी साइज़ 5 एमबी से ज़्यादा नहीं हो सकता. साथ ही, इसमें सिर्फ़ स्ट्रिंग शामिल की जा सकती हैं. यह टैब के हिसाब से होता है, इसलिए इसे वेब वर्कर या सेवा वर्कर से ऐक्सेस नहीं किया जा सकता.

LocalStorage का इस्तेमाल नहीं किया जाना चाहिए, क्योंकि यह सिंक्रोनस है और मुख्य थ्रेड को ब्लॉक कर देगा. इसका साइज़ पांच एमबी से ज़्यादा नहीं होना चाहिए. साथ ही, इसमें सिर्फ़ स्ट्रिंग हो सकती हैं. LocalStorage को वेब वर्कर या सर्विस वर्कर से ऐक्सेस नहीं किया जा सकता.

कुकी का इस्तेमाल कई कामों के लिए किया जाता है. हालांकि, इसका इस्तेमाल स्टोरेज के लिए नहीं किया जाना चाहिए. कुकी हर एचटीटीपी अनुरोध के साथ भेजी जाती हैं. इसलिए, थोड़े से ज़्यादा डेटा को स्टोर करने से, हर वेब अनुरोध का साइज़ काफ़ी बढ़ जाएगा. ये सिंक्रोनस होते हैं और इन्हें वेब वर्कर्स से ऐक्सेस नहीं किया जा सकता. LocalStorage और SessionStorage की तरह, कुकी सिर्फ़ स्ट्रिंग तक सीमित होती हैं.

File System Access API को इस तरह से डिज़ाइन किया गया है कि उपयोगकर्ता अपने लोकल फ़ाइल सिस्टम में मौजूद फ़ाइलों को पढ़ सकें और उनमें बदलाव कर सकें. कोई पेज किसी भी लोकल फ़ाइल को पढ़ने या उसमें बदलाव करने से पहले, उपयोगकर्ता को अनुमति देनी होगी. साथ ही, जब तक किसी फ़ाइल हैंडल को IndexedDB में कैश मेमोरी में सेव नहीं किया जाता, तब तक अनुमतियां सभी सेशन में सेव नहीं रहतीं. File System Access API, एडिटर जैसे इस्तेमाल के उदाहरणों के लिए सबसे सही है. इनमें आपको किसी फ़ाइल को खोलने, उसमें बदलाव करने, और फिर बदलावों को फ़ाइल में सेव करने की ज़रूरत होती है.

फ़ाइल सिस्टम एपीआई और FileWriter API, सैंडबॉक्स किए गए फ़ाइल सिस्टम में फ़ाइलें पढ़ने और लिखने के तरीके उपलब्ध कराते हैं. यह सिंक नहीं होता, लेकिन इसका सुझाव नहीं दिया जाता, क्योंकि यह सिर्फ़ Chromium कोड वाले ब्राउज़र में उपलब्ध है.

कितनी जानकारी सेव की जा सकती है?

कम शब्दों में कहें, तो काफ़ी, कम से कम दो सौ मेगाबाइट और संभावित रूप से सैकड़ों गीगाबाइट या उससे ज़्यादा. ब्राउज़र में स्टोरेज को लागू करने का तरीका अलग-अलग होता है. हालांकि, आम तौर पर उपलब्ध स्टोरेज की मात्रा, डिवाइस में मौजूद स्टोरेज की मात्रा पर निर्भर करती है.

  • Chrome, ब्राउज़र को डिस्क के कुल स्टोरेज का 80% तक इस्तेमाल करने की अनुमति देता है. कोई ऑरिजिन, डिस्क के कुल स्टोरेज का 60% तक इस्तेमाल कर सकता है. StorageManager API का इस्तेमाल करके, यह पता लगाया जा सकता है कि आपके पास कितना स्टोरेज कोटा है. Chromium पर आधारित अन्य ब्राउज़र में ऐसा नहीं हो सकता.
    • गुप्त मोड में, Chrome उस स्टोरेज को कम कर देता है जिसका इस्तेमाल ऑरिजिन, डिस्क के कुल स्टोरेज का करीब 5% तक कर सकता है.
    • अगर उपयोगकर्ता ने Chrome में "सभी विंडो बंद करने पर कुकी और साइट डेटा मिटाएं" को चालू किया है, तो स्टोरेज कोटा काफ़ी कम हो जाता है. यह ज़्यादा से ज़्यादा 300 एमबी तक हो सकता है.
  • Firefox, ब्राउज़र को डिस्क के 50% तक खाली जगह का इस्तेमाल करने की अनुमति देता है. eTLD+1 ग्रुप (उदाहरण के लिए, example.com, www.example.com, और foo.bar.example.com) के लिए, ज़्यादा से ज़्यादा 2 जीबी का इस्तेमाल किया जा सकता है. StorageManager API का इस्तेमाल करके, यह पता लगाया जा सकता है कि अब कितना स्टोरेज बचा है.
  • Safari (डेस्कटॉप और मोबाइल, दोनों) में करीब 1 जीबी तक का डेटा सेव किया जा सकता है. तय सीमा पूरी होने पर, Safari उपयोगकर्ता को इसकी सूचना देगा. साथ ही, 200 एमबी के हिसाब से स्टोरेज की सीमा बढ़ाएगा. मुझे इस बारे में कोई आधिकारिक दस्तावेज़ नहीं मिला.
    • अगर मोबाइल Safari की होम स्क्रीन पर कोई PWA जोड़ा जाता है, तो इससे एक नया स्टोरेज कंटेनर बन जाता है. साथ ही, PWA और मोबाइल Safari के बीच कुछ भी शेयर नहीं किया जाता. इंस्टॉल किए गए किसी PWA के लिए कोटा पूरा होने के बाद, ज़्यादा स्टोरेज का अनुरोध नहीं किया जा सकता.

पहले, अगर कोई साइट सेव किए गए डेटा की तय सीमा से ज़्यादा डेटा सेव करती थी, तो ब्राउज़र उपयोगकर्ता से ज़्यादा डेटा इस्तेमाल करने की अनुमति मांगता था. उदाहरण के लिए, अगर ऑरिजिन ने 50 एमबी से ज़्यादा स्टोरेज का इस्तेमाल किया, तो ब्राउज़र उपयोगकर्ता से 100 एमबी तक स्टोर करने की अनुमति मांगेगा. इसके बाद, 50 एमबी के हिसाब से स्टोरेज बढ़ाने के लिए फिर से पूछेगा.

फ़िलहाल, ज़्यादातर आधुनिक ब्राउज़र, उपयोगकर्ता को कोई सूचना नहीं देंगे. साथ ही, वे किसी साइट को तय कोटा तक कुकी का इस्तेमाल करने की अनुमति देंगे. हालांकि, Safari में ऐसा नहीं होता. स्टोरेज कोटा खत्म होने पर, यह आपको इसके लिए अनुमति मांगता है. अगर कोई ऑरिजिन, तय किए गए कोटे से ज़्यादा डेटा का इस्तेमाल करने की कोशिश करता है, तो डेटा को फिर से लिखने की कोशिशें पूरी नहीं हो पाएंगी.

मैं यह कैसे देखूं कि मेरे पास कितना स्टोरेज है?

कई ब्राउज़र में, StorageManager API का इस्तेमाल करके यह पता लगाया जा सकता है कि ऑरिजिन के पास कितना स्टोरेज उपलब्ध है और वह कितना स्टोरेज इस्तेमाल कर रहा है. यह IndexedDB और Cache API के इस्तेमाल किए गए बाइट की कुल संख्या की जानकारी देता है. साथ ही, इससे यह हिसाब लगाया जा सकता है कि स्टोरेज में कितना स्टोरेज बचा है.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

आपको कोटा से ज़्यादा अनुरोध करने से जुड़ी गड़बड़ियां ठीक करनी होंगी (यहां देखें). कुछ मामलों में, हो सकता है कि उपलब्ध कोटा, स्टोरेज की असल जगह से ज़्यादा हो.

जांच करें

डेवलपमेंट के दौरान, अलग-अलग तरह के स्टोरेज की जांच करने और सेव किए गए सभी डेटा को मिटाने के लिए, अपने ब्राउज़र के DevTools का इस्तेमाल किया जा सकता है.

Chrome 88 में एक नई सुविधा जोड़ी गई है. इसकी मदद से, स्टोरेज पैनल में जाकर, साइट के स्टोरेज कोटा को बदला जा सकता है. इस सुविधा की मदद से, अलग-अलग डिवाइसों को सिम्युलेट किया जा सकता है. साथ ही, डिस्क के कम स्टोरेज वाले मामलों में अपने ऐप्लिकेशन के काम करने के तरीके की जांच की जा सकती है. ऐप्लिकेशन पर जाएं. इसके बाद, स्टोरेज पर जाएं और कस्टम स्टोरेज कोटा को सिम्युलेट करें चेकबॉक्स को चालू करें. इसके बाद, स्टोरेज कोटा को सिम्युलेट करने के लिए कोई मान्य नंबर डालें.

इस गाइड पर काम करते समय, मैंने एक सरल टूल लिखा, ताकि ज़्यादा से ज़्यादा स्टोरेज का इस्तेमाल जल्द से जल्द किया जा सके. यह स्टोरेज के अलग-अलग तरीकों को आज़माने का एक आसान तरीका है. साथ ही, यह भी देखा जा सकता है कि कोटा इस्तेमाल करने पर क्या होता है.

कोटा खत्म होने पर क्या करना चाहिए?

कोटा खत्म होने पर क्या करना चाहिए? सबसे ज़रूरी बात यह है कि आपको हमेशा लिखने से जुड़ी गड़बड़ियों को पकड़ना और उन्हें मैनेज करना चाहिए. भले ही, वह QuotaExceededError हो या कोई और चीज़. इसके बाद, अपने ऐप्लिकेशन के डिज़ाइन के हिसाब से यह तय करें कि इसे कैसे मैनेज किया जाए. उदाहरण के लिए, ऐसा कॉन्टेंट मिटाएं जिसे लंबे समय से ऐक्सेस नहीं किया गया है, साइज़ के हिसाब से डेटा मिटाएं या उपयोगकर्ताओं को यह चुनने का विकल्प दें कि उन्हें क्या मिटाना है.

उपलब्ध कोटा से ज़्यादा स्टोरेज का इस्तेमाल करने पर, IndexedDB और Cache API, दोनों ही DOMError नाम का QuotaExceededError गड़बड़ी का कोड दिखाते हैं.

IndexedDB

अगर ऑरिजिन ने अपने कोटा को पार कर लिया है, तो IndexedDB में लिखने की कोशिशें पूरी नहीं हो पाएंगी. लेन-देन के onabort() हैंडलर को इवेंट पास करके कॉल किया जाएगा. इवेंट में, गड़बड़ी की प्रॉपर्टी में DOMException शामिल होगा. गड़बड़ी name की जांच करने पर QuotaExceededError दिखेगा.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

Cache API

अगर ऑरिजिन ने कोटा पार कर लिया है, तो कैश मेमोरी एपीआई में लिखने की कोशिशों को QuotaExceededError DOMException के साथ अस्वीकार कर दिया जाएगा.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

वीडियो हटाने की प्रोसेस कैसे काम करती है?

वेब स्टोरेज को दो कैटगरी में बांटा गया है: "बेहतरीन कोशिश" और "लगातार". 'सबसे बेहतर तरीके से' का मतलब है कि ब्राउज़र, उपयोगकर्ता को परेशान किए बिना स्टोरेज को खाली कर सकता है. हालांकि, यह लंबे समय तक या अहम डेटा के लिए कम कारगर है. स्टोरेज कम होने पर, स्टोरेज में सेव डेटा अपने-आप नहीं मिटता. उपयोगकर्ता को ब्राउज़र की सेटिंग में जाकर, इस स्टोरेज को मैन्युअल तरीके से मिटाना होगा.

डिफ़ॉल्ट रूप से, किसी साइट का डेटा (इसमें IndexedDB, Cache API वगैरह शामिल हैं) 'बेहतरीन कोशिश' कैटगरी में आता है. इसका मतलब है कि जब तक किसी साइट ने परसिस्टेंट स्टोरेज का अनुरोध नहीं किया है, तब तक ब्राउज़र अपने हिसाब से साइट का डेटा हटा सकता है. उदाहरण के लिए, जब डिवाइस का स्टोरेज कम हो.

सबसे बेहतर कोशिश के लिए, खाता हटाने की नीति यह है:

  • जब ब्राउज़र में जगह कम हो जाएगी, तब Chromium पर आधारित ब्राउज़र, डेटा हटाना शुरू कर देंगे. सबसे पहले, हाल ही में सबसे कम इस्तेमाल किए गए ऑरिजिन से साइट का सारा डेटा मिटाया जाएगा. इसके बाद, अगले ऑरिजिन से डेटा मिटाया जाएगा. ऐसा तब तक किया जाएगा, जब तक ब्राउज़र में जगह खाली नहीं हो जाती.
  • डिस्क में जगह भर जाने पर, Firefox डेटा मिटाना शुरू कर देगा. सबसे पहले, हाल ही में सबसे कम इस्तेमाल किए गए ऑरिजिन से साइट का सारा डेटा मिटाया जाएगा. इसके बाद, अगले ऑरिजिन से डेटा मिटाया जाएगा. ऐसा तब तक किया जाएगा, जब तक ब्राउज़र में स्टोर किए जाने वाले डेटा की तय सीमा पूरी नहीं हो जाती.
  • Safari पहले डेटा को मिटाता नहीं था. हालांकि, हाल ही में उसने लिखने के लिए उपलब्ध सभी स्टोरेज पर, सात दिन का नया कैप लागू किया है (नीचे देखें).

iOS और iPadOS 13.4 और macOS पर Safari 13.1 से, स्क्रिप्ट में लिखे जा सकने वाले सभी स्टोरेज पर सात दिन की सीमा लागू है. इसमें IndexedDB, सेवा वर्कर्स का रजिस्ट्रेशन, और Cache API शामिल हैं. इसका मतलब है कि अगर उपयोगकर्ता साइट के साथ इंटरैक्ट नहीं करता है, तो Safari का इस्तेमाल करने के सात दिन बाद, Safari कैश मेमोरी से सारा कॉन्टेंट हटा देगा. ऐप्लिकेशन हटाने की यह नीति, होम स्क्रीन पर जोड़े गए इंस्टॉल किए गए PWA पर लागू नहीं होती. पूरी जानकारी के लिए, WebKit के ब्लॉग पर तीसरे पक्ष की कुकी को पूरी तरह ब्लॉक करने और अन्य सुविधाओं के बारे में पढ़ें.

स्टोरेज बकेट

Storage Buckets API का मुख्य मकसद, साइटों को कई स्टोरेज बकेट बनाने की सुविधा देना है. इससे ब्राउज़र, हर बकेट को अन्य बकेट से अलग करके मिटा सकता है. इससे डेवलपर, डेटा मिटाने के लिए प्राथमिकता तय कर सकते हैं. इससे यह पक्का किया जा सकता है कि सबसे अहम डेटा मिटाया न जाए.

बोनस: IndexedDB के लिए रैपर का इस्तेमाल क्यों करना चाहिए

IndexedDB एक लो लेवल एपीआई है. इसका इस्तेमाल करने से पहले, इसे सेट अप करना ज़रूरी है. ऐसा करना, कम जटिल डेटा को सेव करने के लिए खास तौर पर मुश्किल हो सकता है. यह एपीआई, ज़्यादातर आधुनिक, 'वादा' पर आधारित एपीआई से अलग है. यह इवेंट पर आधारित है. IndexedDB के लिए idb जैसे प्रॉमिस रैपर, कुछ बेहतरीन सुविधाओं को छिपा देते हैं. हालांकि, सबसे अहम बात यह है कि वे IndexedDB लाइब्रेरी के साथ आने वाली जटिल मशीनरी (जैसे, लेन-देन, स्कीमा वर्शनिंग) को छिपा देते हैं.

बोनस: SQLite Wasm

वेब एसक्यूएल की सुविधा को बंद करने और Chrome से हटाने के बाद, Google ने लोकप्रिय SQLite डेटाबेस के मैनेजर के साथ मिलकर काम किया. इससे, वेब एसक्यूएल की जगह SQLite पर आधारित डेटाबेस उपलब्ध कराया जा सका. इसका इस्तेमाल करने का तरीका जानने के लिए, Origin के निजी फ़ाइल सिस्टम की मदद से ब्राउज़र में SQLite Wasm लेख पढ़ें.

नतीजा

अब स्टोरेज की कमी की समस्या नहीं है. साथ ही, उपयोगकर्ता को ज़्यादा से ज़्यादा डेटा सेव करने के लिए कहा जाने वाला समय भी बीत चुका है. साइटें, अपने काम करने के लिए ज़रूरी सभी संसाधनों और डेटा को असरदार तरीके से सेव कर सकती हैं. StorageManager API का इस्तेमाल करके, यह पता लगाया जा सकता है कि आपके पास कितना स्टोरेज उपलब्ध है और आपने कितना स्टोरेज इस्तेमाल किया है. साथ ही, परसिस्टेंट स्टोरेज की मदद से, जब तक उपयोगकर्ता इसे हटा नहीं देता, तब तक इसे हटाया नहीं जा सकता.

अन्य संसाधन

धन्यवाद

इस गाइड की समीक्षा करने के लिए, Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink, और Victor Costan का खास धन्यवाद. एजी कितामुरा, अड्डी ओसमानी, और मार्क कोहेन का धन्यवाद, जिन्होंने इस लेख के आधार पर मूल लेख लिखे हैं. एइजी ने एक काम का टूल लिखा है, जिसका नाम ब्राउज़र स्टोरेज का गलत इस्तेमाल करने वाला है. यह टूल, मौजूदा व्यवहार की पुष्टि करने में मददगार साबित हुआ. इसकी मदद से, ज़्यादा से ज़्यादा डेटा सेव किया जा सकता है. साथ ही, अपने ब्राउज़र पर स्टोरेज की सीमाएं देखी जा सकती हैं. फ़्रांकोइस ब्यूफ़ोर को धन्यवाद, जिन्होंने Safari के स्टोरेज की सीमाओं का पता लगाने के लिए, इसकी जांच की. साथ ही, थॉमस स्टाइनर को भी धन्यवाद, जिन्होंने ऑरिजिनल निजी फ़ाइल सिस्टम, स्टोरेज बकेट, SQLite Wasm, और साल 2024 में पूरे कॉन्टेंट के अपडेट के बारे में जानकारी जोड़ी.

Unsplash पर मौजूद हीरो इमेज, गिलाउम बोल्डक की है.