सेवा में है

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

डेटा फ़ेच करने का इवेंट

ब्राउज़र सहायता

  • 40
  • 17
  • 44
  • 11.1

सोर्स

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() को प्रॉमिस पास कर सकते हैं, जिसका जवाब जवाब के साथ देना होगा.

जवाब तैयार किए जा रहे हैं

फ़ेच एपीआई की मदद से, अपने 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() का जवाब दें. ऐसा करने के लिए, पहले आपको कैश मेमोरी में खोजना होगा. match() फ़ंक्शन, टॉप लेवल caches इंटरफ़ेस पर उपलब्ध है. यह आपके ऑरिजिन में मौजूद सभी स्टोर या किसी एक ओपन कैश ऑब्जेक्ट पर खोज करता है.

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

कैश मेमोरी में सेव करने की रणनीतियां

सिर्फ़ ब्राउज़र की कैश मेमोरी से फ़ाइलें दिखाना, हर मामले में लागू नहीं होता. उदाहरण के लिए, उपयोगकर्ता या ब्राउज़र, कैश मेमोरी को हटा सकता है. इसलिए, आपको अपने PWA के लिए ऐसेट डिलीवर करने की रणनीतियां खुद तय करनी चाहिए. आप सिर्फ़ एक कैश मेमोरी में सेव करने की रणनीति तक सीमित नहीं हैं. अलग-अलग यूआरएल पैटर्न के लिए, अलग-अलग पैटर्न तय किए जा सकते हैं. उदाहरण के लिए, आपके पास कम से कम यूज़र इंटरफ़ेस (यूआई) एसेट के लिए एक रणनीति, एपीआई कॉल के लिए दूसरी रणनीति, और इमेज और डेटा यूआरएल के लिए तीसरी रणनीति हो सकती है. इसके लिए, ServiceWorkerGlobalScope.onfetch में event.request.url पढ़ें और इसे रेगुलर एक्सप्रेशन या यूआरएल पैटर्न के ज़रिए पार्स करें. (लिखते समय, यूआरएल पैटर्न सभी प्लैटफ़ॉर्म पर काम नहीं करता).

सबसे सामान्य रणनीतियां हैं:

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

पहले कैश मेमोरी में सेव करें

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

&#39;पहले कैश मेमोरी&#39; की रणनीति

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

नेटवर्क पहले

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

Network First के लिए रणनीति

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

सिर्फ़ नेटवर्क

सिर्फ़ नेटवर्क के लिए इस्तेमाल होने वाली रणनीति, ब्राउज़र के किसी सर्विस वर्कर या कैश स्टोरेज एपीआई के बिना काम करने के तरीके से मिलती-जुलती है. किसी संसाधन को सिर्फ़ तब दिखाने का अनुरोध किया जाता है, जब उसे नेटवर्क से फ़ेच किया जा सके. यह अक्सर, सिर्फ़ ऑनलाइन एपीआई अनुरोध जैसे संसाधनों के लिए काम का होता है.

&#39;सिर्फ़ नेटवर्क&#39; के लिए रणनीति

सिर्फ़ कैश मेमोरी

सिर्फ़ कैश मेमोरी से जुड़ी रणनीति यह पक्का करती है कि अनुरोध कभी भी नेटवर्क को न भेजे जाएं. मिलने वाले सभी अनुरोधों के जवाब, कैश मेमोरी में पहले से भरे आइटम से दिए जाते हैं. यह कोड सिर्फ़ कैश मेमोरी का जवाब देने के लिए, कैश मेमोरी के match तरीके के साथ fetch इवेंट हैंडलर का इस्तेमाल करता है:

self.addEventListener("fetch", event => {
   event.respondWith(caches.match(event.request));
});

सिर्फ़ कैश मेमोरी से जुड़ी रणनीति.

कस्टम रणनीतियां

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

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

ऐसेट अपडेट की जा रही हैं

अपने PWA की कैश मेमोरी में सेव की गई ऐसेट को अप-टू-डेट रखना एक चुनौती हो सकती है. हालांकि, पुरानी रणनीति के साथ फिर से पुष्टि करने की रणनीति ऐसा करने का एक तरीका है, लेकिन यह सिर्फ़ एक ही तरीका नहीं है. चैप्टर अपडेट करें में, आपको अपने ऐप्लिकेशन के कॉन्टेंट और ऐसेट को अपडेट रखने की अलग-अलग तकनीकें सीखने को मिलेंगी.

रिसॉर्स