ब्राउज़र में डेटा सेव करने के कई विकल्प होते हैं. इनमें से कौनसा विकल्प आपकी ज़रूरतों के हिसाब से सबसे सही है?
चलते-फिरते इंटरनेट कनेक्शन ठीक से काम नहीं करते या उपलब्ध नहीं होते. इसलिए, प्रोग्रेसिव वेब ऐप्लिकेशन में ऑफ़लाइन काम करने की सुविधा और भरोसेमंद परफ़ॉर्मेंस जैसी सुविधाएं आम तौर पर उपलब्ध होती हैं. वायरलेस नेटवर्क की अच्छी कनेक्टिविटी होने पर भी, कैश मेमोरी और स्टोरेज की अन्य तकनीकों का सही तरीके से इस्तेमाल करने पर, उपयोगकर्ता अनुभव को बेहतर बनाया जा सकता है. आपके पास अपने स्टैटिक ऐप्लिकेशन रिसॉर्स (एचटीएमएल, JavaScript, सीएसएस, इमेज वगैरह) और डेटा (उपयोगकर्ता का डेटा, समाचार लेख वगैरह) को कैश मेमोरी में सेव करने के कई तरीके हैं. हालांकि, सबसे सही समाधान कौनसा है? कितना डेटा सेव किया जा सकता है? इसे मिटने से कैसे रोका जा सकता है?
मुझे किसका इस्तेमाल करना चाहिए?
यहां संसाधनों को सेव करने के लिए एक सामान्य सुझाव दिया गया है:
- अपने ऐप्लिकेशन को लोड करने के लिए ज़रूरी नेटवर्क संसाधनों के लिए, Cache Storage API का इस्तेमाल करें. यह service workers का हिस्सा है.
- फ़ाइल पर आधारित कॉन्टेंट के लिए, Origin Private File System (OPFS) का इस्तेमाल करें.
- अन्य डेटा के लिए, IndexedDB का इस्तेमाल करें. इसके साथ, promises wrapper का इस्तेमाल करें.
IndexedDB, OPFS, और Cache Storage API, सभी मॉडर्न ब्राउज़र में काम करते हैं.
ये असिंक्रोनस होते हैं और मुख्य थ्रेड को ब्लॉक नहीं करते. हालांकि, OPFS का एक सिंक्रोनस वर्शन भी है, जो सिर्फ़ वेब वर्कर में उपलब्ध है. इन्हें window ऑब्जेक्ट, वेब वर्कर, और सर्विस वर्कर से ऐक्सेस किया जा सकता है. इसलिए, इन्हें आपके कोड में कहीं भी इस्तेमाल किया जा सकता है.
स्टोरेज के अन्य तरीकों के बारे में क्या जानकारी है?
ब्राउज़र में डेटा सेव करने के कई अन्य तरीके भी उपलब्ध हैं. हालांकि, इनका इस्तेमाल सीमित तौर पर किया जाता है और इनसे परफ़ॉर्मेंस से जुड़ी गंभीर समस्याएं हो सकती हैं.
SessionStorage किसी टैब के लिए खास होता है. साथ ही, यह टैब के बंद होने तक ही उपलब्ध रहता है. इसका इस्तेमाल, सेशन के हिसाब से कम मात्रा में जानकारी सेव करने के लिए किया जा सकता है. उदाहरण के लिए, IndexedDB कुंजी. इसका इस्तेमाल सावधानी से करना चाहिए, क्योंकि यह सिंक्रोनस है और मुख्य थ्रेड को ब्लॉक कर देगा. यह करीब 5 एमबी तक सीमित है और इसमें सिर्फ़ स्ट्रिंग हो सकती हैं. यह टैब के हिसाब से काम करता है. इसलिए, इसे वेब वर्कर या सर्विस वर्कर से ऐक्सेस नहीं किया जा सकता.
LocalStorage का इस्तेमाल नहीं करना चाहिए, क्योंकि यह सिंक्रोनस है और मुख्य थ्रेड को ब्लॉक कर देगा. यह करीब 5 एमबी तक सीमित है और इसमें सिर्फ़ स्ट्रिंग हो सकती हैं. वेब वर्कर या सर्विस वर्कर से 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 एमबी के इंक्रीमेंट में सीमा बढ़ाएगा. मुझे इस बारे में कोई आधिकारिक दस्तावेज़ नहीं मिला.
- अगर किसी PWA को मोबाइल Safari पर होम स्क्रीन में जोड़ा जाता है, तो यह एक नया स्टोरेज कंटेनर बनाता है. साथ ही, 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
अगर ऑरिजिन ने अपना कोटा पार कर लिया है, तो 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 पहले डेटा नहीं मिटाता था. हालांकि, हाल ही में उसने सभी राइटेबल स्टोरेज के लिए सात दिनों की नई सीमा लागू की है. इसके बारे में यहां बताया गया है.
macOS पर iOS और iPadOS 13.4 और Safari 13.1 से, स्क्रिप्ट के ज़रिए लिखे जा सकने वाले सभी स्टोरेज पर सात दिनों की सीमा लागू होती है. इसमें IndexedDB, सर्विस वर्कर रजिस्ट्रेशन, और Cache API शामिल हैं. इसका मतलब है कि अगर उपयोगकर्ता सात दिनों तक Safari का इस्तेमाल करता है और साइट से इंटरैक्ट नहीं करता है, तो Safari, कैश मेमोरी से सभी कॉन्टेंट हटा देगा. बेदखली से जुड़ी यह नीति, होम स्क्रीन पर जोड़े गए इंस्टॉल किए गए PWA पर लागू नहीं होती है. पूरी जानकारी के लिए, WebKit ब्लॉग पर तीसरे पक्ष की कुकी को पूरी तरह से ब्लॉक करने और अन्य सुविधाओं के बारे में जानकारी लेख पढ़ें.
स्टोरेज बकेट
Storage Buckets API का मुख्य मकसद, साइटों को कई स्टोरेज बकेट बनाने की सुविधा देना है. इसमें ब्राउज़र, हर बकेट को अन्य बकेट से अलग करके मिटा सकता है. इससे डेवलपर, डेटा को हटाने के लिए प्राथमिकता तय कर सकते हैं. इससे यह पक्का किया जा सकता है कि सबसे ज़रूरी डेटा न मिटे.
बोनस: IndexedDB के लिए रैपर का इस्तेमाल क्यों करें
IndexedDB एक लो लेवल एपीआई है. इसका इस्तेमाल करने से पहले, इसे सेटअप करना ज़रूरी होता है. यह कम जटिलता वाले डेटा को सेव करने के लिए, खास तौर पर मुश्किल हो सकता है. प्रॉमिस पर आधारित ज़्यादातर आधुनिक एपीआई के उलट, यह इवेंट पर आधारित है. IndexedDB के लिए idb जैसे Promise रैपर, कुछ बेहतरीन सुविधाओं को छिपा देते हैं. हालांकि, इससे ज़्यादा ज़रूरी यह है कि ये IndexedDB लाइब्रेरी के साथ आने वाली जटिल मशीनरी (जैसे, लेन-देन, स्कीमा वर्शनिंग) को छिपा देते हैं.
बोनस: SQLite Wasm
वेब एसक्यूएल की सुविधा बंद होने और Chrome से हटाए जाने के बाद, Google ने लोकप्रिय SQLite डेटाबेस के रखरखाव करने वालों के साथ मिलकर काम किया. इसका मकसद, SQLite पर आधारित वेब एसक्यूएल का विकल्प उपलब्ध कराना था. इसे इस्तेमाल करने के तरीके के बारे में जानने के लिए, Origin Private File System की मदद से ब्राउज़र में SQLite Wasm पढ़ें.
नतीजा
अब स्टोरेज की सीमाएं नहीं हैं. साथ ही, उपयोगकर्ता को ज़्यादा से ज़्यादा डेटा सेव करने के लिए भी नहीं कहा जाता. साइटें, चलाने के लिए ज़रूरी सभी संसाधनों और डेटा को असरदार तरीके से सेव कर सकती हैं. StorageManager API का इस्तेमाल करके, यह पता लगाया जा सकता है कि आपके पास कितना स्टोरेज उपलब्ध है और आपने कितना स्टोरेज इस्तेमाल किया है. साथ ही, परसिस्टेंट स्टोरेज की मदद से, उपयोगकर्ता के हटाए जाने तक इसे सुरक्षित रखा जा सकता है.
अन्य संसाधन
धन्यवाद
इस गाइड की समीक्षा करने के लिए, जैरिड गुडमैन, फ़िल वॉल्टन, एजी कितामुरा, डैनियल मर्फ़ी, डार्विन हुआंग, जोश बेल, मारिन क्रुसेलब्रिंक, और विक्टर कोस्टन का खास धन्यवाद. एजी कितामुरा, ऐडी ओस्मानी, और मार्क कोहेन को धन्यवाद. उन्होंने ओरिजनल लेख लिखे थे जिनके आधार पर यह लेख तैयार किया गया है. एजी ने Browser Storage Abuser नाम का एक काम का टूल बनाया था. यह टूल, मौजूदा व्यवहार की पुष्टि करने में मददगार था. इससे ज़्यादा से ज़्यादा डेटा सेव किया जा सकता है. साथ ही, ब्राउज़र पर स्टोरेज की सीमाएं देखी जा सकती हैं. हम फ़्रांस्वा बोफ़ोर्ट को धन्यवाद देते हैं, जिन्होंने Safari की स्टोरेज सीमा के बारे में जानकारी दी. साथ ही, हम थॉमस स्टाइनर को धन्यवाद देते हैं, जिन्होंने ओरिजिन प्राइवेट फ़ाइल सिस्टम, स्टोरेज बकेट, SQLite Wasm, और 2024 में कॉन्टेंट अपडेट के बारे में जानकारी दी.