ऐप्लिकेशन कैश का उपयोग करने के बारे में नौसिखियों की गाइड

एरिक बिडेलमैन

शुरुआती जानकारी

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

  1. ऑफ़लाइन ब्राउज़िंग - उपयोगकर्ता ऑफ़लाइन होने पर भी आपकी पूरी साइट पर नेविगेट कर सकते हैं
  2. गति - संसाधन सीधे डिस्क से आते हैं, नेटवर्क से नहीं.
  3. सुविधाजनक - अगर आपकी साइट "रखरखाव" के लिए बंद हो जाती है (जैसा कि, किसी ने गलती से सब कुछ बंद कर दिया), तो आपके उपयोगकर्ताओं को ऑफ़लाइन अनुभव मिलेगा

ऐप्लिकेशन कैश (या Appकैश) की मदद से डेवलपर तय कर सकता है कि ब्राउज़र को किन फ़ाइलों को कैश मेमोरी में सेव करना चाहिए और ऑफ़लाइन उपयोगकर्ताओं के लिए उपलब्ध कराना चाहिए. आपका ऐप्लिकेशन लोड होगा और ठीक से काम करेगा, भले ही उपयोगकर्ता ऑफ़लाइन रहते हुए 'रीफ़्रेश करें' बटन दबाएं.

कैश मेनिफ़ेस्ट फ़ाइल

कैश मेनिफ़ेस्ट फ़ाइल एक सामान्य टेक्स्ट फ़ाइल होती है. इसमें उन संसाधनों की सूची होती है जिन्हें ब्राउज़र को ऑफ़लाइन ऐक्सेस के लिए कैश मेमोरी में सेव करना चाहिए.

मेनिफ़ेस्ट फ़ाइल का रेफ़रंस देना

किसी ऐप्लिकेशन के लिए ऐप्लिकेशन कैश मेमोरी चालू करने के लिए, दस्तावेज़ के html टैग में मेनिफ़ेस्ट एट्रिब्यूट शामिल करें:

<html manifest="example.appcache">
  ...
</html>

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

Chrome में about://appcache-internals/ पर जाकर, आप ऐप्लिकेशन कैश से कंट्रोल किए जाने वाले यूआरएल देख सकते हैं. यहां से कैश मेमोरी में सेव किया गया डेटा मिटाया जा सकता है और एंट्री देखी जा सकती हैं. Firefox में मिलते-जुलते डेवलपर टूल भी हैं.

manifest एट्रिब्यूट किसी पूरे यूआरएल या मिलते-जुलते पाथ की जानकारी दे सकता है. हालांकि, पूरा यूआरएल और वेब ऐप्लिकेशन एक ही ऑरिजिन में होना चाहिए. मेनिफ़ेस्ट फ़ाइल में कोई भी फ़ाइल एक्सटेंशन हो सकता है, लेकिन उसे सही माइम-टाइप के साथ दिखाना ज़रूरी है (नीचे देखें).

<html manifest="http://www.example.com/example.mf">
  ...
</html>

मेनिफ़ेस्ट फ़ाइल को माइम-टाइप text/cache-manifest के साथ दिखाया जाना चाहिए. आपको अपने वेब सर्वर या .htaccess कॉन्फ़िगरेशन में, कस्टम फ़ाइल टाइप जोड़ना पड़ सकता है.

उदाहरण के लिए, Apache में इस माइम-टाइप को दिखाने के लिए, अपनी कॉन्फ़िगरेशन फ़ाइल में यह लाइन जोड़ें:

AddType text/cache-manifest .appcache

या Google App Engine में अपनी app.yaml फ़ाइल में:

- url: /mystaticdir/(.*\.appcache)
  static_files: mystaticdir/\1
  mime_type: text/cache-manifest
  upload: mystaticdir/(.*\.appcache)

इस ज़रूरत को कुछ समय पहले स्पेसिफ़िकेशन से हटा दिया गया था. अब Chrome, Safari, और Firefox के सबसे नए वर्शन में इसकी ज़रूरत नहीं है. हालांकि, पुराने ब्राउज़र और IE11 में काम करने के लिए, आपको माइम-टाइप की ज़रूरत होगी.

मेनिफ़ेस्ट फ़ाइल का स्ट्रक्चर

मेनिफ़ेस्ट एक अलग फ़ाइल है, जिसे आपने एचटीएमएल एलिमेंट पर मौजूद मेनिफ़ेस्ट एट्रिब्यूट का इस्तेमाल करके लिंक किया है. सामान्य मेनिफ़ेस्ट कुछ ऐसा दिखता है:

CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js

इस उदाहरण में, उस पेज पर चार फ़ाइलें कैश मेमोरी में सेव की जाएंगी जिन पर इस मेनिफ़ेस्ट फ़ाइल की जानकारी दी गई है.

यहां ध्यान देने वाली कुछ बातें बताई गई हैं:

  • CACHE MANIFEST स्ट्रिंग पहली लाइन है और यह ज़रूरी है.
  • फ़ाइलें किसी दूसरे डोमेन की हो सकती हैं
  • कुछ ब्राउज़र आपके ऐप्लिकेशन के लिए उपलब्ध स्टोरेज कोटा पर पाबंदियां लगाते हैं. उदाहरण के लिए, Chrome में, Appकैश, TEMPORARY स्टोरेज के शेयर किए गए पूल का इस्तेमाल करता है, जिसे दूसरे ऑफ़लाइन एपीआई शेयर कर सकते हैं. अगर Chrome Web Store के लिए ऐप्लिकेशन का इस्तेमाल किया जा रहा है, तो unlimitedStorage का इस्तेमाल करके, वह पाबंदी हटा दी जाती है.
  • अगर मेनिफ़ेस्ट ही 404 या 410 दिखाता है, तो कैश मेमोरी मिटा दी जाती है.
  • अगर मेनिफ़ेस्ट या इसमें बताया गया कोई संसाधन डाउनलोड नहीं हो पाता, तो कैश मेमोरी अपडेट करने की पूरी प्रोसेस काम नहीं करेगी. विफल होने की स्थिति में ब्राउज़र, ऐप्लिकेशन की पुरानी कैश मेमोरी का इस्तेमाल करता रहेगा.

आइए, ज़्यादा जटिल उदाहरण देखते हैं:

CACHE MANIFEST
# 2010-06-18:v2

# Explicitly cached 'master entries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js

# Resources that require the user to be online.
NETWORK:
*

# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg

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

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

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

मेनिफ़ेस्ट में तीन अलग-अलग सेक्शन हो सकते हैं: CACHE, NETWORK, और FALLBACK.

CACHE:
यह एंट्री के लिए डिफ़ॉल्ट सेक्शन है. इस हेडर के तहत (या CACHE MANIFEST के तुरंत बाद) सूची में शामिल फ़ाइलों को पहली बार डाउनलोड करने के बाद, साफ़ तौर पर कैश मेमोरी में सेव किया जाएगा. NETWORK:
इस सेक्शन में शामिल फ़ाइलें, कैश मेमोरी में मौजूद न होने पर नेटवर्क से आ सकती हैं. ऐसा न होने पर, नेटवर्क का इस्तेमाल नहीं किया जाता, भले ही उपयोगकर्ता ऑनलाइन हो. यहां खास यूआरएल को व्हाइटलिस्ट में जोड़ा जा सकता है या "" को चुना जा सकता है, जिससे सभी यूआरएल को अनुमति मिलती है. ज़्यादातर साइटों को "" की ज़रूरत होती है. FALLBACK:
अगर किसी संसाधन को ऐक्सेस नहीं किया जा सकता, तो फ़ॉलबैक पेजों की जानकारी देने वाला वैकल्पिक सेक्शन. पहला यूआरआई संसाधन है, दूसरा फ़ॉलबैक इस्तेमाल किया जाता है. नेटवर्क अनुरोध के पूरा न होने या किसी तरह की गड़बड़ी की वजह से, इसे इस्तेमाल किया जाता है. दोनों यूआरआई और मेनिफ़ेस्ट फ़ाइल, दोनों एक ही ऑरिजिन से होनी चाहिए. आपके पास यूआरएल प्रीफ़िक्स के साथ-साथ चुनिंदा यूआरएल को कैप्चर करने का विकल्प है. "images/large/", यूआरएल से हुई गड़बड़ियों को कैप्चर करेगा, जैसे कि "images/large/whatever/img.jpg".

नीचे दिया गया मेनिफ़ेस्ट एक "कैच-ऑल" पेज (Offline.html) के बारे में बताता है, जो तब दिखाया जाएगा जब उपयोगकर्ता ऑफ़लाइन होने पर साइट के रूट को ऐक्सेस करने की कोशिश करेगा. इसमें यह भी बताया गया है कि अन्य सभी संसाधनों (उदाहरण के लिए, जो रिमोट किसी साइट पर हैं) के लिए इंटरनेट कनेक्शन ज़रूरी है.

CACHE MANIFEST
# 2010-06-18:v3

# Explicitly cached entries
index.html
css/style.css

# offline.html will be displayed if the user is offline
FALLBACK:
/ /offline.html

# All other resources (e.g. sites) require the user to be online.
NETWORK:
*

# Additional resources to cache
CACHE:
images/logo1.png
images/logo2.png
images/logo3.png

कैश मेमोरी को अपडेट किया जा रहा है

ऐप्लिकेशन के ऑफ़लाइन होने पर, वह तब तक कैश मेमोरी में सेव रहता है, जब तक इनमें से कोई एक कार्रवाई नहीं होती:

  1. उपयोगकर्ता आपकी साइट के लिए, अपने ब्राउज़र का डेटा स्टोरेज खाली कर देता है.
  2. मेनिफ़ेस्ट फ़ाइल में बदलाव किया गया है. ध्यान दें: मेनिफ़ेस्ट में बताई गई किसी फ़ाइल को अपडेट करने का मतलब यह नहीं है कि ब्राउज़र उस संसाधन को फिर से सेव कर लेगा. मेनिफ़ेस्ट फ़ाइल में बदलाव करना ज़रूरी है.

कैश मेमोरी का स्टेटस

window.applicationCache ऑब्जेक्ट, ब्राउज़र की ऐप्लिकेशन कैश मेमोरी पर आपका प्रोग्राम के हिसाब से ऐक्सेस करता है. इसकी status प्रॉपर्टी से, कैश मेमोरी की मौजूदा स्थिति को देखा जा सकता है:

var appCache = window.applicationCache;

switch (appCache.status) {
case appCache.UNCACHED: // UNCACHED == 0
return 'UNCACHED';
break;
case appCache.IDLE: // IDLE == 1
return 'IDLE';
break;
case appCache.CHECKING: // CHECKING == 2
return 'CHECKING';
break;
case appCache.DOWNLOADING: // DOWNLOADING == 3
return 'DOWNLOADING';
break;
case appCache.UPDATEREADY:  // UPDATEREADY == 4
return 'UPDATEREADY';
break;
case appCache.OBSOLETE: // OBSOLETE == 5
return 'OBSOLETE';
break;
default:
return 'UKNOWN CACHE STATUS';
break;
};

प्रोग्राम के हिसाब से, मेनिफ़ेस्ट के अपडेट देखने के लिए, पहले applicationCache.update() को कॉल करें. इससे उपयोगकर्ता की कैश मेमोरी अपडेट करने की कोशिश की जाएगी (जिसके लिए मेनिफ़ेस्ट फ़ाइल को बदलना ज़रूरी है). आखिर में, जब applicationCache.status अपनी UPDATEREADY स्थिति में होता है, तो applicationCache.swapCache() को कॉल करने पर पुरानी कैश मेमोरी को नए कैश में बदल दिया जाएगा.

var appCache = window.applicationCache;

appCache.update(); // Attempt to update the user's cache.

...

if (appCache.status == window.applicationCache.UPDATEREADY) {
appCache.swapCache();  // The fetch was successful, swap in the new cache.
}

अच्छी खबर: आप इसे ऑटोमेट कर सकते हैं. लोगों को अपनी साइट के नए वर्शन पर अपडेट करने के लिए, पेज लोड होने पर updateready इवेंट को मॉनिटर करने के लिए लिसनर सेट करें:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {

window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    // Browser downloaded a new app cache.
    if (confirm('A new version of this site is available. Load it?')) {
    window.location.reload();
    }
} else {
    // Manifest didn't changed. Nothing new to server.
}
}, false);

}, false);

Appकैश इवेंट

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

function handleCacheEvent(e) {
//...
}

function handleCacheError(e) {
alert('Error: Cache failed to update!');
};

// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);

// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);

// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);

// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);

// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);

// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);

// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);

// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);

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

References