अब तक,
Cache
इंटरफ़ेस.
सर्विस वर्कर का असरदार तरीके से इस्तेमाल करने के लिए, कैश मेमोरी में डेटा सेव करने की एक या उससे ज़्यादा रणनीतियों को अपनाना ज़रूरी है,
इसके लिए, Cache
इंटरफ़ेस को समझना ज़रूरी है.
कैश मेमोरी में सेव करने की रणनीति, सर्विस वर्कर के fetch
इवेंट और Cache
इंटरफ़ेस के बीच होने वाला इंटरैक्शन है.
कैश मेमोरी में सेव करने की रणनीति किस तरह लिखी जाएगी, यह इस बात पर निर्भर करता है कि
उदाहरण के लिए, दस्तावेज़ों की तुलना में स्टैटिक ऐसेट के अनुरोधों को मैनेज करना बेहतर हो सकता है,
और इससे कैश मेमोरी की रणनीति तैयार होने के तरीके पर असर पड़ता है.
रणनीतियों के बारे में बात करने से पहले,
आइए, इस बारे में बात करते हैं कि Cache
इंटरफ़ेस क्या नहीं है, यह क्या है,
साथ ही, इसमें आपको सर्विस वर्कर कैश मेमोरी को मैनेज करने के लिए उपलब्ध कुछ तरीकों की जानकारी भी मिलेगी.
Cache
इंटरफ़ेस और एचटीटीपी कैश मेमोरी
अगर आपने Cache
इंटरफ़ेस पर पहले काम नहीं किया है, तो
आपको ऐसा लग सकता है कि आप उसे ऐसा ही समझें,
या कम से कम एचटीटीपी कैश से जुड़ी होगी. हालांकि, ऐसा नहीं है.
Cache
इंटरफ़ेस, कैश मेमोरी में सेव करने का एक तरीका है. यह एचटीटीपी कैश मेमोरी से पूरी तरह अलग होता है.- जो भी हो
Cache-Control
एचटीटीपी कैश मेमोरी में सेव होने वाले कॉन्फ़िगरेशन का इस्तेमाल करने पर,Cache
इंटरफ़ेस में सेव की जाने वाली ऐसेट पर कोई असर नहीं पड़ता.
ब्राउज़र कैश मेमोरी को लेयर के तौर पर समझने से मदद मिलती है. एचटीटीपी कैश, का-वैल्यू पेयर से मिलने वाला लो-लेवल कैश मेमोरी है. इसे एचटीटीपी हेडर में दिशा-निर्देशों के साथ पेश किया जाता है.
वहीं दूसरी ओर, Cache
इंटरफ़ेस एक हाई-लेवल कैश मेमोरी है, जो JavaScript API की मदद से काम करता है.
यह सामान्य एचटीटीपी की-वैल्यू पेयर का इस्तेमाल करने की तुलना में ज़्यादा विकल्प देता है.
और यह कैश मेमोरी में डेटा सेव करने की रणनीतियों का आधा हिस्सा है.
सर्विस वर्कर कैश के लिए कुछ ज़रूरी एपीआई तरीके यहां दिए गए हैं:
CacheStorage.open
नयाCache
इंस्टेंस बनाने के लिए.Cache.add
औरCache.put
का इस्तेमाल करके, नेटवर्क रिस्पॉन्स को सर्विस वर्कर कैश में स्टोर किया जा सकता है.Cache.match
Cache
इंस्टेंस में कैश मेमोरी में सेव किए गए रिस्पॉन्स को ढूंढने के लिए.Cache.delete
Cache
इंस्टेंस से कैश मेमोरी में सेव किए गए जवाब को हटाने के लिए.
ये बस कुछ ही हैं. इसके अलावा, काम के दूसरे तरीके भी हैं. लेकिन ये बुनियादी जानकारी हैं, जिनका इस्तेमाल आप इस गाइड में बाद में करेंगे.
fetch
का सादगी भरा इवेंट
कैशिंग की रणनीति का दूसरा आधा हिस्सा सर्विस वर्कर का होता है
fetch
इवेंट.
इस दस्तावेज़ में, अब तक आपको "नेटवर्क अनुरोधों में रुकावट डालने" के बारे में थोड़ा-बहुत पता चला है,
और सर्विस वर्कर के अंदर fetch
इवेंट ऐसा होता है:
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
self.addEventListener('install', (event) => {
event.waitUntil(caches.open(cacheName));
});
self.addEventListener('fetch', async (event) => {
// Is this a request for an image?
if (event.request.destination === 'image') {
// Open the cache
event.respondWith(caches.open(cacheName).then((cache) => {
// Respond with the image from the cache or from the network
return cache.match(event.request).then((cachedResponse) => {
return cachedResponse || fetch(event.request.url).then((fetchedResponse) => {
// Add the network response to the cache for future visits.
// Note: we need to make a copy of the response to save it in
// the cache and use the original as the request response.
cache.put(event.request, fetchedResponse.clone());
// Return the network response
return fetchedResponse;
});
});
}));
} else {
return;
}
});
यह एक खिलौने का उदाहरण है—और इसे अपने हिसाब से इस्तेमाल किया जा सकता है—लेकिन यहां इस बात की झलक मिलती है कि सर्विस वर्कर क्या-क्या कर सकते हैं. ऊपर दिया गया कोड ये काम करता है:
- अनुरोध की
destination
प्रॉपर्टी की जांच करके देखें कि यह इमेज के लिए किया गया अनुरोध है या नहीं. - अगर इमेज सर्विस वर्कर की कैश मेमोरी में है, तो उसे वहां से दिखाएं. अगर नहीं, तो नेटवर्क से इमेज फ़ेच करें, रिस्पॉन्स को कैश मेमोरी में सेव करें और नेटवर्क रिस्पॉन्स को दिखाएं.
- बाकी सभी अनुरोध, सर्विस वर्कर से भेजे जाते हैं और कैश मेमोरी से इंटरैक्शन नहीं होता.
फ़ेच किए गए event
ऑब्जेक्ट में
request
प्रॉपर्टी
ये कुछ काम की जानकारी होती हैं, जिनकी मदद से हर अनुरोध के टाइप का पता लगाया जा सकता है:
url
जो उस नेटवर्क अनुरोध का यूआरएल है जिसे फ़िलहालfetch
इवेंट मैनेज कर रहा है.method
यह अनुरोध का तरीका है (उदाहरण के लिए,GET
याPOST
).mode
इससे अनुरोध के मोड की जानकारी मिलती है.'navigate'
वैल्यू का इस्तेमाल, अक्सर एचटीएमएल दस्तावेज़ों के अनुरोधों को अन्य अनुरोधों से अलग करने के लिए किया जाता है.destination
इससे, अनुरोध किए गए कॉन्टेंट के टाइप की जानकारी मिलती है. साथ ही, अनुरोध की गई ऐसेट के फ़ाइल एक्सटेंशन का इस्तेमाल नहीं किया जा सकता.
एक बार फिर से, एसिंक्रोनस गेम को ही नाम दिया गया है.
आपको याद होगा कि install
इवेंट में
event.waitUntil
जो वादा लेता है और एक्टिवेशन जारी रखने से पहले उसके ठीक होने का इंतज़ार करता है.
fetch
इवेंट ऐसा ही ऑफ़र करता है
event.respondWith
तरीका
जिसका इस्तेमाल करके, एसिंक्रोनस के नतीजे को वापस दिया जा सकता है
fetch
अनुरोध
या Cache
इंटरफ़ेस के
match
तरीका.
कैश मेमोरी में सेव करने की रणनीतियां
अब आपको Cache
इंस्टेंस और fetch
इवेंट हैंडलर के बारे में थोड़ी जानकारी हो गई है,
अब आप सर्विस वर्कर को कैश मेमोरी में सेव करने की रणनीतियों के बारे में ज़्यादा जान सकते हैं.
इसका इस्तेमाल कभी-कभी किया जा सकता है, लेकिन
इस गाइड में उन रणनीतियों का इस्तेमाल किया जाएगा जो Workbox के साथ भेजी जाती हैं,
ताकि आप यह जान सकें कि Workbox के अंदरूनी हिस्सों में क्या चल रहा है.
सिर्फ़ कैश मेमोरी
चलिए, कैश मेमोरी में सेव करने की एक आसान रणनीति से शुरुआत करते हैं. इस रणनीति को हम "सिर्फ़ कैश मेमोरी" कहते हैं. बात बस ऐसी होती है: जब सर्विस वर्कर के पास पेज का कंट्रोल होता है, मेल खाने वाले अनुरोध कभी भी कैश मेमोरी में जाएंगे. इसका मतलब है कि किसी भी कैश मेमोरी में सेव की गई ऐसेट को पहले से कैश मेमोरी में सेव करना होगा, ताकि पैटर्न काम कर सके, और यह कि उन एसेट को कैश मेमोरी में तब तक अपडेट नहीं किया जाएगा, जब तक सर्विस वर्कर को अपडेट नहीं किया जाता.
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
// Assets to precache
const precachedAssets = [
'/possum1.jpg',
'/possum2.jpg',
'/possum3.jpg',
'/possum4.jpg'
];
self.addEventListener('install', (event) => {
// Precache assets on install
event.waitUntil(caches.open(cacheName).then((cache) => {
return cache.addAll(precachedAssets);
}));
});
self.addEventListener('fetch', (event) => {
// Is this one of our precached assets?
const url = new URL(event.request.url);
const isPrecachedRequest = precachedAssets.includes(url.pathname);
if (isPrecachedRequest) {
// Grab the precached asset from the cache
event.respondWith(caches.open(cacheName).then((cache) => {
return cache.match(event.request.url);
}));
} else {
// Go to the network
return;
}
});
ऊपर, इंस्टॉल के समय ऐसेट के कलेक्शन को पहले से कैश मेमोरी में सेव किया जाता है.
जब सर्विस वर्कर, फ़ेच को हैंडल करता है,
हम यह जांच करते हैं कि fetch
इवेंट से मैनेज किया जाने वाला अनुरोध यूआरएल, पहले से कैश की गई ऐसेट के कलेक्शन में है या नहीं.
अगर ऐसा है, तो हम कैश मेमोरी से संसाधन लेते हैं और नेटवर्क को छोड़ देते हैं.
अन्य अनुरोध नेटवर्क से होकर गुज़रते हैं,
और सिर्फ़ नेटवर्क की.
इस रणनीति को काम करते हुए देखने के लिए,
अपना कंसोल खोलकर यह डेमो देखें.
सिर्फ़ नेटवर्क
"सिर्फ़ कैश मेमोरी" के उलट "सिर्फ़ नेटवर्क" है, जहां सर्विस वर्कर कैश से इंटरैक्शन किए बिना, सर्विस वर्कर के ज़रिए नेटवर्क पर अनुरोध भेजा जाता है. कॉन्टेंट को अप-टू-डेट रखने के लिए यह एक अच्छी रणनीति है (मार्कअप के बारे में सोचें), लेकिन समस्या यह है कि यह उपयोगकर्ता के ऑफ़लाइन होने पर कभी भी काम नहीं करेगा.
यह पक्का करने का मतलब है कि नेटवर्क में कोई अनुरोध पास हो जाता है. इसका मतलब यह है कि मिलते-जुलते अनुरोध के लिए event.respondWith
को कॉल नहीं किया जाएगा.
अगर आपको अश्लील कॉन्टेंट दिखाना है,
नेटवर्क से किए जाने वाले अनुरोधों के लिए, आपके पास fetch
इवेंट कॉलबैक में एक खाली return;
स्लैप करने का विकल्प होता है.
"सिर्फ़ कैश मेमोरी" में ऐसा होता है ऐसे अनुरोधों के लिए रणनीति का डेमो जो पहले से कैश मेमोरी में सेव नहीं किए गए हैं.
पहले कैश मेमोरी का इस्तेमाल करें, ताकि नेटवर्क का इस्तेमाल किया जा सके
इस रणनीति में चीज़ों को और बेहतर बनाने में मदद मिलती है. मेल खाने वाले अनुरोधों के लिए, प्रक्रिया इस तरह होती है:
- अनुरोध कैश मेमोरी पर हिट करता है. अगर ऐसेट कैश मेमोरी में है, तो उसे वहां से अपलोड करें.
- अगर अनुरोध कैश मेमोरी में सेव नहीं है, तो नेटवर्क पर जाएं.
- नेटवर्क अनुरोध पूरा हो जाने पर, उसे कैश मेमोरी में जोड़ें, फिर नेटवर्क से रिस्पॉन्स दें.
यहां इस रणनीति का एक उदाहरण दिया गया है. इसे आज़माने के लिए, लाइव डेमो:
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
self.addEventListener('fetch', (event) => {
// Check if this is a request for an image
if (event.request.destination === 'image') {
event.respondWith(caches.open(cacheName).then((cache) => {
// Go to the cache first
return cache.match(event.request.url).then((cachedResponse) => {
// Return a cached response if we have one
if (cachedResponse) {
return cachedResponse;
}
// Otherwise, hit the network
return fetch(event.request).then((fetchedResponse) => {
// Add the network response to the cache for later visits
cache.put(event.request, fetchedResponse.clone());
// Return the network response
return fetchedResponse;
});
});
}));
} else {
return;
}
});
हालांकि, इस उदाहरण में सिर्फ़ इमेज शामिल हैं, यह सभी स्टैटिक ऐसेट (जैसे, CSS, JavaScript, इमेज, और फ़ॉन्ट) पर लागू करने के लिए बेहतरीन रणनीति है, खास तौर पर, हैश-वर्शन वाले. यह सर्वर पर, कॉन्टेंट अपडेट होने की फ़्रीक्वेंसी की जांच को अलग-अलग तरीके से करता है. इससे एचटीटीपी कैश मेमोरी में सेव किया जा सकता है. इससे, नहीं बदली जा सकने वाली ऐसेट के लिए, स्पीड को बूस्ट किया जा सकता है. इससे भी अहम बात यह है कि कैश मेमोरी में सेव की गई कोई भी ऐसेट, ऑफ़लाइन उपलब्ध होगी.
सबसे पहले, कैश मेमोरी का इस्तेमाल करें
अगर आप "पहले कैश मेमोरी, दूसरे नेटवर्क" को फ़्लिप करते हैं सिर पर, तो आपको "नेटवर्क पहले" मिलता है, दूसरा कैश मेमोरी" जो ऐसा लगता है:
- अनुरोध करने के लिए, पहले नेटवर्क पर जाएं और रिस्पॉन्स को कैश मेमोरी में रखें.
- अगर आप बाद में ऑफ़लाइन हैं, कैश मेमोरी में सेव किए गए उस जवाब के नए वर्शन पर वापस जाते हैं.
यह रणनीति एचटीएमएल या एपीआई अनुरोधों के लिए तब सबसे अच्छी होती है, जब, जब आप ऑनलाइन हों, तब आपको किसी संसाधन का सबसे नया वर्शन चाहिए, अभी भी सबसे नए उपलब्ध वर्शन को ऑफ़लाइन ऐक्सेस देना चाहते हों. यहां बताया गया है कि एचटीएमएल के लिए अनुरोधों पर लागू होने पर, यह कुछ ऐसा दिख सकता है:
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
self.addEventListener('fetch', (event) => {
// Check if this is a navigation request
if (event.request.mode === 'navigate') {
// Open the cache
event.respondWith(caches.open(cacheName).then((cache) => {
// Go to the network first
return fetch(event.request.url).then((fetchedResponse) => {
cache.put(event.request, fetchedResponse.clone());
return fetchedResponse;
}).catch(() => {
// If the network is unavailable, get
return cache.match(event.request.url);
});
}));
} else {
return;
}
});
इसे डेमो में आज़माया जा सकता है. सबसे पहले, इस पेज पर जाएं. एचटीएमएल रिस्पॉन्स को कैश मेमोरी में रखने से पहले, आपको पेज को फिर से लोड करना पड़ सकता है. फिर अपने डेवलपर टूल में, ऑफ़लाइन कनेक्शन को सिम्युलेट किया जा सकता है, और फिर से लोड करें. पिछला उपलब्ध वर्शन, कैश मेमोरी से तुरंत दिखाया जाएगा.
उन स्थितियों में, जब ऑफ़लाइन सुविधा ज़रूरी होती है, लेकिन आपको उस क्षमता को, किसी बिट मार्कअप या एपीआई डेटा के सबसे नए वर्शन के ऐक्सेस के साथ संतुलित करना होगा, "पहले नेटवर्क, दूसरे पर कैश मेमोरी" उस लक्ष्य को पाने के लिए एक मज़बूत रणनीति है.
फिर से पुष्टि करने के दौरान पुरानी जानकारी
हमने अब तक जिन रणनीतियों के बारे में बात की है उनमें से, "दोबारा पुष्टि करने के दौरान पुरानी जानकारी" तो सबसे मुश्किल काम है. यह कुछ हद तक पिछली दो रणनीतियों जैसा है, लेकिन इस प्रोसेस में, संसाधन तक पहुंचने की स्पीड को प्राथमिकता दी जाती है. साथ ही, वह बैकग्राउंड में अप-टू-डेट रहता है. यह रणनीति कुछ इस तरह से काम करेगी:
- पहली बार किसी ऐसेट के लिए अनुरोध करने पर, उसे नेटवर्क से फ़ेच करें. उसे कैश मेमोरी में रखें और नेटवर्क रिस्पॉन्स दिखाएं.
- बाद के अनुरोधों पर, पहले कैश मेमोरी से ऐसेट दिखाएं. इसके बाद, "बैकग्राउंड में" ऐसेट चलाएं. नेटवर्क से इसके लिए फिर से अनुरोध करें और ऐसेट की कैश एंट्री को अपडेट करें.
- इसके बाद के अनुरोधों के लिए, आपको उस नेटवर्क से पिछला वर्शन मिलेगा जिसे पिछले चरण में कैश मेमोरी में रखा गया था.
यह उन चीज़ों के लिए एक बेहतरीन रणनीति है जिन्हें अप टू डेट रखना ज़रूरी क्रम है, लेकिन ज़रूरी नहीं हैं. किसी सोशल मीडिया साइट के अवतार के बारे में सोचें. जब उपयोगकर्ता आस-पास होते हैं, तो उन्हें अपडेट हो जाता है, लेकिन हर अनुरोध पर सबसे नया वर्शन ज़रूरी नहीं है.
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
self.addEventListener('fetch', (event) => {
if (event.request.destination === 'image') {
event.respondWith(caches.open(cacheName).then((cache) => {
return cache.match(event.request).then((cachedResponse) => {
const fetchedResponse = fetch(event.request).then((networkResponse) => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return cachedResponse || fetchedResponse;
});
}));
} else {
return;
}
});
इसे यहाँ काम करते हुए देखा जा सकता है
एक और लाइव डेमो आ गया,
अगर आप अपने ब्राउज़र के डेवलपर टूल के नेटवर्क टैब पर ध्यान देते हैं,
और उसका CacheStorage
व्यूअर (अगर आपके ब्राउज़र के डेवलपर टूल में ऐसा कोई टूल हो).
वर्कबॉक्स की ओर आगे!
सर्विस वर्कर के एपीआई की हमारी समीक्षा नीचे दी गई है. एपीआई की मदद से भी, इसका मतलब है कि आपने इस बारे में काफ़ी जान लिया है कि Workbox के साथ काम करने के लिए, सीधे तौर पर सर्विस वर्कर का इस्तेमाल कैसे किया जाए!