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

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

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

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

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

  • आपके ऐप्लिकेशन और फ़ाइल-आधारित कॉन्टेंट को लोड करने के लिए ज़रूरी नेटवर्क संसाधनों के लिए, cache Storage API का इस्तेमाल करें. यह सेवा वर्कर का हिस्सा होता है.
  • दूसरे डेटा के लिए, प्रॉमिस रैपर के साथ IndexedDB का इस्तेमाल करें.

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

अन्य स्टोरेज तरीके क्या हैं?

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

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

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

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

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

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

WebSQL का इस्तेमाल नहीं किया जाना चाहिए. साथ ही, मौजूदा इस्तेमाल को IndexedDB पर माइग्रेट किया जाना चाहिए. करीब सभी बड़े ब्राउज़र से सहायता को हटा दिया गया है. W3C ने 2010 में वेब एसक्यूएल की खास जानकारी को बनाए रखना बंद कर दिया, जिसमें आगे अपडेट करने की कोई योजना नहीं थी.

ऐप्लिकेशन की कैश मेमोरी का इस्तेमाल नहीं किया जाना चाहिए. साथ ही, मौजूदा इस्तेमाल को सर्विस वर्कर और कैश एपीआई पर माइग्रेट किया जाना चाहिए. इसे रोक दिया गया है और आने वाले समय में ब्राउज़र से सहायता हटा दी जाएगी.

कितना डेटा स्टोर किया जा सकता है?

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

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

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

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

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

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

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.`);
}

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

जांच करें

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

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

DevTools स्टोरेज पैनल.

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

कोटा से ज़्यादा स्टोरेज इस्तेमाल करने की समस्या को कैसे मैनेज करें?

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

जब आपका उपलब्ध कोटा खत्म हो जाता है, तो IndexedDB और कैश API, दोनों ही QuotaExceededError नाम का DOMError दिखाते हैं.

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
  }
};

कैश एपीआई

अगर ऑरिजिन अपने कोटा से ज़्यादा हो गया है, तो कैश एपीआई में लिखने की कोशिश करने पर, 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 पर आधारित ब्राउज़र डेटा को निकालना शुरू कर देते हैं. इस तरह, सबसे कम हाल ही में इस्तेमाल किए गए ऑरिजिन से सारा साइट डेटा मिटाया जाता है. इसके बाद, ब्राउज़र की डेटा सीमा खत्म होने तक डेटा सेव किया जाता है.
  • Internet Explorer 10+ डेटा नहीं हटाएगा, लेकिन मूल वर्शन से अब और डेटा नहीं हटाएगा.
  • डिस्क में उपलब्ध जगह भर जाने पर, Firefox डेटा को मिटाना शुरू कर देगा. साथ ही, सबसे कम हाल ही में इस्तेमाल किए गए ऑरिजिन से साइट के सभी डेटा को सबसे पहले हटाएगा. इसके बाद, ब्राउज़र की तय सीमा से ज़्यादा डेटा मिटा दिया जाएगा.
  • Safari से पहले डेटा नहीं हटाया जाता था, लेकिन हाल ही में सभी लिखने लायक स्टोरेज पर एक नई सीमा लागू की गई है (नीचे देखें).

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

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

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

नतीजा

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

ज़्यादा रिसॉर्स

धन्यवाद

इस लेख को पढ़ने के लिए, जेरिड गुडमैन, फ़िल वॉल्टन, आइजी कितामुरा, डैनियल मर्फ़ी, डार्विन हुआंग, जॉश बेल, मैरीजन क्रुसलब्रिंक, और विक्टर कोस्टन का विशेष धन्यवाद. ईजी कितामुरा, एडी ओस्मानी, और मार्क कोहेन का धन्यवाद जिन्होंने इस लेख पर आधारित मूल लेख लिखे थे. Eiji ने ब्राउज़र स्टोरेज एब्यूसर नाम का एक मददगार टूल लिखा. इससे उनकी मौजूदा गतिविधियों की पुष्टि करने में मदद मिली. इससे आपको ज़्यादा से ज़्यादा डेटा सेव करने और ब्राउज़र पर स्टोरेज की सीमाएं देखने की सुविधा मिलती है. फ़्रैंकॉइस ब्यूफ़ोर्ट का धन्यवाद जिन्होंने Safari की मेमोरी की सीमा का पता लगाने के लिए खुदाई की.

हीरो इमेज, Unस्प्लैश चैनल पर गियौम बोल्डक ने बनाई है.