सर्विस वर्कर कैशिंग के लिए रणनीतियां

अब तक, 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;
  }
});

यह एक खिलौने का उदाहरण है—और इसे अपने हिसाब से इस्तेमाल किया जा सकता है—लेकिन यहां इस बात की झलक मिलती है कि सर्विस वर्कर क्या-क्या कर सकते हैं. ऊपर दिया गया कोड ये काम करता है:

  1. अनुरोध की destination प्रॉपर्टी की जांच करके देखें कि यह इमेज के लिए किया गया अनुरोध है या नहीं.
  2. अगर इमेज सर्विस वर्कर की कैश मेमोरी में है, तो उसे वहां से दिखाएं. अगर नहीं, तो नेटवर्क से इमेज फ़ेच करें, रिस्पॉन्स को कैश मेमोरी में सेव करें और नेटवर्क रिस्पॉन्स को दिखाएं.
  3. बाकी सभी अनुरोध, सर्विस वर्कर से भेजे जाते हैं और कैश मेमोरी से इंटरैक्शन नहीं होता.

फ़ेच किए गए 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; स्लैप करने का विकल्प होता है. "सिर्फ़ कैश मेमोरी" में ऐसा होता है ऐसे अनुरोधों के लिए रणनीति का डेमो जो पहले से कैश मेमोरी में सेव नहीं किए गए हैं.

पहले कैश मेमोरी का इस्तेमाल करें, ताकि नेटवर्क का इस्तेमाल किया जा सके

यह विकल्प कैश मेमोरी में सेव न होने पर, पेज से सर्विस वर्कर, कैश मेमोरी, और फिर नेटवर्क तक का फ़्लो दिखाता है.

इस रणनीति में चीज़ों को और बेहतर बनाने में मदद मिलती है. मेल खाने वाले अनुरोधों के लिए, प्रक्रिया इस तरह होती है:

  1. अनुरोध कैश मेमोरी पर हिट करता है. अगर ऐसेट कैश मेमोरी में है, तो उसे वहां से अपलोड करें.
  2. अगर अनुरोध कैश मेमोरी में सेव नहीं है, तो नेटवर्क पर जाएं.
  3. नेटवर्क अनुरोध पूरा हो जाने पर, उसे कैश मेमोरी में जोड़ें, फिर नेटवर्क से रिस्पॉन्स दें.

यहां इस रणनीति का एक उदाहरण दिया गया है. इसे आज़माने के लिए, लाइव डेमो:

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

सबसे पहले, कैश मेमोरी का इस्तेमाल करें

यह रिपोर्ट, एक पेज से दूसरे पेज पर, सर्विस वर्कर, और फिर नेटवर्क न होने पर कैश मेमोरी में सेव होने का फ़्लो दिखाती है.

अगर आप "पहले कैश मेमोरी, दूसरे नेटवर्क" को फ़्लिप करते हैं सिर पर, तो आपको "नेटवर्क पहले" मिलता है, दूसरा कैश मेमोरी" जो ऐसा लगता है:

  1. अनुरोध करने के लिए, पहले नेटवर्क पर जाएं और रिस्पॉन्स को कैश मेमोरी में रखें.
  2. अगर आप बाद में ऑफ़लाइन हैं, कैश मेमोरी में सेव किए गए उस जवाब के नए वर्शन पर वापस जाते हैं.

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

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

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

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

फिर से पुष्टि करने के दौरान पुरानी जानकारी

यह रिपोर्ट, पेज से सर्विस वर्कर, कैश मेमोरी, और नेटवर्क से कैश मेमोरी तक जाने का फ़्लो दिखाती है.

हमने अब तक जिन रणनीतियों के बारे में बात की है उनमें से, "दोबारा पुष्टि करने के दौरान पुरानी जानकारी" तो सबसे मुश्किल काम है. यह कुछ हद तक पिछली दो रणनीतियों जैसा है, लेकिन इस प्रोसेस में, संसाधन तक पहुंचने की स्पीड को प्राथमिकता दी जाती है. साथ ही, वह बैकग्राउंड में अप-टू-डेट रहता है. यह रणनीति कुछ इस तरह से काम करेगी:

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

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

// 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 के साथ काम करने के लिए, सीधे तौर पर सर्विस वर्कर का इस्तेमाल कैसे किया जाए!