प्रोग्रेसिव वेब ऐप्लिकेशन का एक अहम पहलू यह है कि वे भरोसेमंद होते हैं; वे तेज़ी से एसेट लोड कर सकते हैं, ताकि उपयोगकर्ताओं की दिलचस्पी बनी रहे और नेटवर्क खराब होने पर भी तुरंत सुझाव या राय दी जा सके. यह कैसे मुमकिन है? सर्विस वर्कर fetch
इवेंट को धन्यवाद.
फ़ेच इवेंट
ब्राउज़र सहायता
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
fetch
इवेंट की मदद से, हम सर्विस वर्कर के स्कोप में, PWA के हर नेटवर्क अनुरोध को इंटरसेप्ट कर सकते हैं. यह अनुरोध, एक ही ऑरिजिन और क्रॉस-ऑरिजिन, दोनों के लिए किया जाता है. नेविगेशन और एसेट के अनुरोधों के अलावा, इंस्टॉल किए गए सर्विस वर्कर से फ़ेच करने से, साइट के पहले लोड के बाद पेज विज़िट को नेटवर्क कॉल के बिना रेंडर किया जा सकता है.
fetch
हैंडलर को ऐप्लिकेशन से सभी अनुरोध मिलते हैं. इनमें यूआरएल और एचटीटीपी हेडर शामिल हैं. साथ ही, इससे ऐप्लिकेशन डेवलपर यह तय कर सकता है कि इन अनुरोधों को कैसे प्रोसेस किया जाए.
आपका सर्विस वर्कर, नेटवर्क पर अनुरोध भेज सकता है, कैश मेमोरी में सेव किए गए पिछले रिस्पॉन्स से जवाब दे सकता है या नया रिस्पॉन्स बना सकता है. यह आपकी पसंद है. इसका एक आसान सा उदाहरण देखें :
self.addEventListener("fetch", event => {
console.log(`URL requested: ${event.request.url}`);
});
अनुरोध का जवाब देना
जब आपके सर्विस वर्कर से कोई अनुरोध किया जाता है, तो आपके पास ये दो विकल्प होते हैं: आप उसे अनदेखा कर सकते हैं, जिससे वह नेटवर्क पर चला जाता है या आप उसका जवाब दे सकते हैं. सर्विस वर्कर के अनुरोधों का जवाब देने का तरीका यह है कि उपयोगकर्ता के ऑफ़लाइन होने पर भी यह चुना जा सकता है कि क्या और वह वापस आपके PWA में कैसे आएगा.
आने वाले अनुरोध का जवाब देने के लिए, fetch
इवेंट हैंडलर में जाकर event.respondWith()
को इस तरह से कॉल करें:
// fetch event handler in your service worker file
self.addEventListener("fetch", event => {
const response = .... // a response or a Promise of response
event.respondWith(response);
});
आपको respondWith()
को सिंक करके कॉल करना होगा और आपको Response ऑब्जेक्ट दिखाना होगा. हालांकि, फ़ेच इवेंट हैंडलर की प्रोसेस पूरी होने के बाद, respondWith()
को कॉल नहीं किया जा सकता. जैसे, एक साथ काम न करने वाले कॉल में. अगर आपको पूरे जवाब का इंतज़ार करना है, तो respondWith()
को प्रॉमिस पास करें. इसके बाद, उस प्रॉमिस को जवाब के साथ ठीक किया जा सकता है.
जवाब तैयार किए जा रहे हैं
Get API की मदद से आप अपने JavaScript कोड में एचटीटीपी रिस्पॉन्स बना सकते हैं. इन रिस्पॉन्स को कैश मेमोरी एपीआई का इस्तेमाल करके कैश मेमोरी में सेव किया जा सकता है. साथ ही, इस तरह से रिस्पॉन्स दिया जाता है, जैसे कि ये वेब सर्वर से आ रहे हों.
जवाब तैयार करने के लिए, नया Response
ऑब्जेक्ट बनाएं. इसके बाद, ऑब्जेक्ट का मुख्य हिस्सा और स्टेटस और हेडर जैसे विकल्प सेट करें:
const simpleResponse = new Response("Body of the HTTP response");
const options = {
status: 200,
headers: {
'Content-type': 'text/html'
}
};
const htmlResponse = new Response("<b>HTML</b> content", options)
कैश मेमोरी से जवाब दिया जा रहा है
अब आपको पता है कि सर्विस वर्कर से एचटीटीपी रिस्पॉन्स कैसे मिलते हैं, अब डिवाइस पर ऐसेट सेव करने के लिए, कैश मेमोरी स्टोरेज इंटरफ़ेस का इस्तेमाल करें.
कैश मेमोरी में सेव किए गए डेटा को स्टोर करने वाले एपीआई का इस्तेमाल करके, यह देखा जा सकता है कि PWA से मिला अनुरोध, कैश मेमोरी में उपलब्ध है या नहीं. अगर उपलब्ध है, तो respondWith()
का इस्तेमाल करके अनुरोध का जवाब दें.
ऐसा करने के लिए, आपको सबसे पहले कैश मेमोरी में खोजना होगा. टॉप लेवल caches
इंटरफ़ेस पर मौजूद match()
फ़ंक्शन, आपके ऑरिजिन में मौजूद सभी स्टोर या किसी एक ओपन कैश ऑब्जेक्ट पर खोज करता है.
match()
फ़ंक्शन को तर्क के तौर पर कोई एचटीटीपी अनुरोध या यूआरएल मिलता है और यह ऐसा प्रॉमिस रिस्पॉन्स देता है जिसका समाधान, उससे जुड़ी कुंजी के रिस्पॉन्स से हो जाता है.
// Global search on all caches in the current origin
caches.match(urlOrRequest).then(response => {
console.log(response ? response : "It's not in the cache");
});
// Cache-specific search
caches.open("pwa-assets").then(cache => {
cache.match(urlOrRequest).then(response => {
console.log(response ? response : "It's not in the cache");
});
});
कैश मेमोरी में सेव करने की रणनीतियां
सिर्फ़ ब्राउज़र की कैश मेमोरी से फ़ाइलें दिखाने की सुविधा, इस्तेमाल के सभी उदाहरणों के लिए सही नहीं होती. उदाहरण के लिए, उपयोगकर्ता या ब्राउज़र, कैश मेमोरी को हटा सकता है. इसलिए, आपको अपने पीडब्ल्यूए के लिए ऐसेट डिलीवर करने की रणनीतियां तय करनी चाहिए.
आपके पास, कैश मेमोरी में सेव करने की एक ही रणनीति का इस्तेमाल करने का विकल्प है. अलग-अलग यूआरएल पैटर्न के लिए, अलग-अलग पैटर्न तय किए जा सकते हैं. उदाहरण के लिए, यूज़र इंटरफ़ेस (यूआई) की कम से कम ऐसेट के लिए एक रणनीति, एपीआई कॉल के लिए दूसरी, और इमेज और डेटा यूआरएल के लिए तीसरी रणनीति हो सकती है.
ऐसा करने के लिए, ServiceWorkerGlobalScope.onfetch
में event.request.url
पढ़ें और इसे रेगुलर एक्सप्रेशन या यूआरएल पैटर्न की मदद से पार्स करें. (लिखते समय, यूआरएल पैटर्न की सुविधा सभी प्लैटफ़ॉर्म पर काम नहीं करती).
सबसे सामान्य रणनीतियां ये हैं:
- पहले कैश मेमोरी
- पहले, कैश मेमोरी में सेव किए गए जवाब को खोजता है और न मिलने पर नेटवर्क पर वापस चला जाता है.
- नेटवर्क फ़र्स्ट
- पहले नेटवर्क से रिस्पॉन्स का अनुरोध करता है और कोई रिस्पॉन्स नहीं मिलने पर कैश मेमोरी में रिस्पॉन्स की जांच करता है.
- फिर से सत्यापित करते समय पुरानी जानकारी
- कैश मेमोरी से जवाब देता है, जबकि बैकग्राउंड में नए वर्शन का अनुरोध करता है. साथ ही, अगली बार एसेट का अनुरोध करने पर उसे कैश मेमोरी में सेव करता है.
- सिर्फ़ नेटवर्क
- हमेशा नेटवर्क से जवाब मिलने पर या गड़बड़ी के मैसेज के साथ जवाब देने पर. कैश मेमोरी के बारे में कभी भी सलाह नहीं दी जाती.
- केवल-कैश
- हमेशा कैश मेमोरी से मिले जवाब के साथ या गड़बड़ियों के साथ जवाब देने पर. नेटवर्क से कभी भी सलाह नहीं ली जाएगी. इस रणनीति का इस्तेमाल करके दिखाई जाने वाली ऐसेट का अनुरोध करने से पहले, उन्हें कैश मेमोरी में जोड़ना होगा.
पहले कैश मेमोरी
इस रणनीति का इस्तेमाल करके सर्विस वर्कर, कैश मेमोरी में मेल खाने वाला अनुरोध खोजता है और कैश मेमोरी में सेव किए जाने पर उससे जुड़ा रिस्पॉन्स देता है. ऐसा न होने पर, यह नेटवर्क से रिस्पॉन्स लेता है. हालांकि, आगे के कॉल के लिए कैश मेमोरी को अपडेट किया जा सकता है. अगर कैश मेमोरी से जुड़ा कोई रिस्पॉन्स या नेटवर्क रिस्पॉन्स नहीं मिलता है, तो अनुरोध में गड़बड़ी होगी. नेटवर्क पर जाए बिना ऐसेट को तेज़ी से दिखाया जाता है. इसलिए, यह रणनीति अपडेट होने के बजाय परफ़ॉर्मेंस को प्राथमिकता देती है.
self.addEventListener("fetch", event => {
event.respondWith(
caches.match(event.request)
.then(cachedResponse => {
// It can update the cache to serve updated content on the next request
return cachedResponse || fetch(event.request);
}
)
)
});
नेटवर्क पहले
यह रणनीति 'कैश फ़र्स्ट' रणनीति का हिस्सा है; यह जांच करता है कि नेटवर्क से अनुरोध पूरा किया जा सकता है या नहीं. अगर अनुरोध पूरा नहीं हो पाता है, तो उसे कैश मेमोरी से वापस पाने की कोशिश करता है. पहले कैश मेमोरी की तरह. अगर नेटवर्क रिस्पॉन्स या कैश मेमोरी से जुड़ा कोई रिस्पॉन्स नहीं मिलता है, तो अनुरोध में गड़बड़ी होगी. आम तौर पर, कैश मेमोरी से मिलने वाले रिस्पॉन्स के मुकाबले नेटवर्क से रिस्पॉन्स मिलने में ज़्यादा समय लगता है. यह रणनीति, परफ़ॉर्मेंस के बजाय अपडेट किए गए कॉन्टेंट को प्राथमिकता देती है.
self.addEventListener("fetch", event => {
event.respondWith(
fetch(event.request)
.catch(error => {
return caches.match(event.request) ;
})
);
});
फिर से पुष्टि करते समय पुरानी जानकारी मौजूद है
रणनीति को फिर से पुष्टि करने के दौरान अगर पुरानी जानकारी आती है, तो कैश मेमोरी में सेव किया गया रिस्पॉन्स तुरंत दिखता है. इसके बाद, अपडेट के लिए नेटवर्क की जांच करता है. साथ ही, कैश मेमोरी में सेव किया गया रिस्पॉन्स मिलने पर उसे बदल देता है. यह रणनीति हमेशा नेटवर्क के लिए अनुरोध करती है, क्योंकि कैश मेमोरी में सेव किया गया संसाधन मिलने पर भी यह अगले अनुरोध में अपडेट किए गए वर्शन का इस्तेमाल करने के लिए, नेटवर्क से मिले कॉन्टेंट के साथ कैश मेमोरी में मौजूद जानकारी को अपडेट करने की कोशिश करती है. इस वजह से, इस रणनीति की मदद से कैश मेमोरी में पहले सेव की गई जानकारी को तुरंत दिखाने की रणनीति का फ़ायदा लिया जा सकता है. साथ ही, बैकग्राउंड में कैश मेमोरी को अपडेट किया जा सकता है.
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cachedResponse => {
const networkFetch = fetch(event.request).then(response => {
// update the cache with a clone of the network response
const responseClone = response.clone()
caches.open(url.searchParams.get('name')).then(cache => {
cache.put(event.request, responseClone)
})
return response
}).catch(function (reason) {
console.error('ServiceWorker fetch failed: ', reason)
})
// prioritize cached response over network
return cachedResponse || networkFetch
}
)
)
})
सिर्फ़ नेटवर्क
सिर्फ़ नेटवर्क की रणनीति उसी तरह काम करती है जैसे ब्राउज़र, सर्विस वर्कर या कैश मेमोरी एपीआई के बिना काम करते हैं. अनुरोध करने पर कोई संसाधन सिर्फ़ तब दिखेगा, जब उसे नेटवर्क से फ़ेच किया जा सकेगा. यह अक्सर सिर्फ़-ऑनलाइन-ऑनलाइन एपीआई अनुरोधों के लिए मददगार होता है.
सिर्फ़ कैश मेमोरी
सिर्फ़ कैश मेमोरी की रणनीति से यह पक्का किया जाता है कि अनुरोध कभी भी नेटवर्क पर न जाएं; आने वाले सभी अनुरोधों का जवाब, पहले से भरे गए कैश आइटम का इस्तेमाल करके दिया जाता है. नीचे दिया गया कोड सिर्फ़ कैश मेमोरी से जवाब देने के लिए, कैश मेमोरी के लिए match
तरीके के साथ fetch
इवेंट हैंडलर का इस्तेमाल करता है:
self.addEventListener("fetch", event => {
event.respondWith(caches.match(event.request));
});
कस्टम रणनीतियां
हालांकि, ऊपर दी गई कैश मेमोरी में डेटा सेव करने की सामान्य रणनीतियां हैं, लेकिन अपने सर्विस वर्कर और अनुरोधों को मैनेज करने के तरीके की ज़िम्मेदारी आपकी है. अगर इनमें से कोई भी आपकी ज़रूरतों के मुताबिक नहीं है, तो अपनी ज़रूरत के हिसाब से कैंपेन बनाएं.
उदाहरण के लिए, अपडेट किए गए कॉन्टेंट को प्राथमिकता देने के लिए, नेटवर्क को प्राथमिकता देने वाली रणनीति का इस्तेमाल किया जा सकता है. हालांकि, ऐसा सिर्फ़ तब किया जा सकता है, जब जवाब सेट किए गए थ्रेशोल्ड के अंदर हो. कैश मेमोरी में सेव किए गए रिस्पॉन्स को नेटवर्क रिस्पॉन्स के साथ मर्ज करके भी सर्विस वर्कर से मिलने वाले जटिल रिस्पॉन्स को तैयार किया जा सकता है.
ऐसेट अपडेट करना
अपने PWA की कैश मेमोरी में सेव की गई ऐसेट को अप-टू-डेट रखना मुश्किल हो सकता है. रणनीति को दोबारा सत्यापित करते समय पुरानी जानकारी होने से भी ऐसा किया जा सकता है. हालांकि, यह सिर्फ़ यही नहीं है. चैप्टर अपडेट करें में, आपको अपने ऐप्लिकेशन के कॉन्टेंट और ऐसेट को अपडेट रखने की अलग-अलग तकनीकों के बारे में जानकारी मिलेगी.