सर्विस वर्कर की मानसिकता

सेवा वर्कर्स के बारे में सोचते समय क्या ध्यान रखना चाहिए.

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

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

Google Developers और मैंने हाल ही में एक प्रोजेक्ट पर मिलकर काम किया है. यह प्रोजेक्ट, Service Workies है. यह एक ऐसा गेम है जिसमें बिना किसी शुल्क के, सर्विस वर्कर के बारे में जानकारी मिलती है. इसे बनाते समय और सेवा वर्कर के जटिल पहलुओं पर काम करते समय, मुझे कुछ समस्याएं हुईं. मुझे सबसे ज़्यादा मदद तब मिली, जब मैंने कुछ मेटाफ़ोर इस्तेमाल किए. इस पोस्ट में, हम इन मानसिक मॉडल के बारे में जानेंगे. साथ ही, उन विरोधाभासी लक्षणों के बारे में भी जानेंगे जिनकी वजह से सेवा देने वाले लोग, मुश्किल और बेहतरीन दोनों तरह के होते हैं.

एक जैसे, लेकिन अलग-अलग

अपने सेवा वर्कर को कोड करते समय, आपको कई चीज़ें जानी-पहचानी लगेंगी. आपको JavaScript भाषा की अपनी पसंदीदा नई सुविधाओं का इस्तेमाल करने का मौका मिलता है. यूज़र इंटरफ़ेस (यूआई) इवेंट की तरह ही, लाइफ़साइकल इवेंट को भी सुना जाता है. प्रोमिस की मदद से, कंट्रोल फ़्लो को मैनेज किया जाता है.

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

नई लेयर

आम तौर पर, साइट बनाते समय आपको सिर्फ़ दो लेयर के बारे में सोचना होता है: क्लाइंट और सर्वर. सेवा वर्कर एक नई लेयर है, जो बीच में मौजूद होती है.

सेवा वर्कर, क्लाइंट और सर्वर के बीच मिडल लेयर के तौर पर काम करता है

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

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

Service Workies गेम में, हम सेवा वर्कर के लाइफ़साइकल के बारे में कई जानकारी देते हैं. साथ ही, आपको इसकी मदद से काम करने का ढेर सारा अभ्यास भी देते हैं.

ज़्यादा सुविधाएं, लेकिन सीमित

अपनी साइट पर सर्विस वर्कर का इस्तेमाल करने से आपको कई फ़ायदे मिलते हैं. आपकी साइट:

  • उपयोगकर्ता के ऑफ़लाइन होने पर भी बिना किसी रुकावट के काम करना
  • कैश मेमोरी की मदद से, परफ़ॉर्मेंस में काफ़ी सुधार पाएं
  • पुश नोटिफ़िकेशन का इस्तेमाल करना
  • PWA के तौर पर इंस्टॉल किया जा सकता है

सेवा वर्कर ज़्यादा काम कर सकते हैं, लेकिन डिज़ाइन की वजह से उनकी क्षमता सीमित होती है. वे आपकी साइट के साथ सिंक करके या उसी थ्रेड में कोई भी काम नहीं कर सकते. इसका मतलब है कि आपके पास इनका ऐक्सेस नहीं होगा:

  • localStorage
  • डीओएम
  • विंडो

अच्छी बात यह है कि आपका पेज, अपने सेवा वर्कर के साथ कई तरीकों से कम्यूनिकेट कर सकता है. इनमें डायरेक्ट postMessage, एक-से-एक मैसेज चैनल, और एक-से-कई ब्रॉडकास्ट चैनल शामिल हैं.

लंबे समय तक चलने वाले, लेकिन कम समय तक चलने वाले

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

Service Workies में, हमने इस कॉन्सेप्ट को दिखाने के लिए, अनुरोधों को इंटरसेप्ट और हैंडल करने वाले Kolohe (एक दोस्ताना सेवा वर्कर) का इस्तेमाल किया है.

बंद किया गया

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

waitUntil

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

इस उदाहरण से ब्राउज़र को पता चलता है कि assets कैश मेमोरी बनने और उसमें तलवार की तस्वीर भरने तक, हमारा सेवा वर्कर इंस्टॉल नहीं होगा:

self.addEventListener("install", event => {
  event.waitUntil(
    caches.open("assets").then(cache => {
      return cache.addAll(["/weapons/sword/blade.png"]);
    })
  );
});

ग्लोबल स्टेटस पर नज़र रखें

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

ग्लोबल स्टेट का इस्तेमाल करने वाले इस उदाहरण पर ध्यान दें:

const favoriteNumber = Math.random();
let hasHandledARequest = false;

self.addEventListener("fetch", event => {
  console.log(favoriteNumber);
  console.log(hasHandledARequest);
  hasHandledARequest = true;
});

हर अनुरोध पर, यह सेवा वर्कर एक नंबर लॉग करेगा—उदाहरण के लिए, 0.13981866382421893. hasHandledARequest वैरिएबल भी true में बदल जाता है. अब सेवा वर्कर कुछ समय के लिए काम नहीं करता, इसलिए ब्राउज़र उसे बंद कर देता है. अगली बार जब कोई अनुरोध होगा, तब सर्विस वर्कर की फिर से ज़रूरत होगी. इसलिए, ब्राउज़र उसे फिर से चालू कर देगा. इसकी स्क्रिप्ट का फिर से आकलन किया जाता है. अब hasHandledARequest को false पर रीसेट कर दिया गया है और favoriteNumber पूरी तरह से अलग है—0.5907281835659033.

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

Service Workies के तीसरे चैप्टर में, हमने बंद किए गए सर्विस वर्कर को ऐसे दिखाया है कि वह 'जागने' का इंतज़ार करते हुए अपना सारा रंग खो देता है.

बंद किए गए सर्विस वर्कर को विज़ुअलाइज़ करना

एक साथ, लेकिन अलग-अलग

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

किसी दूसरे सर्विस वर्कर की कैश मेमोरी में बदलाव करना

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

  • SW2, उस कैश मेमोरी को मिटा सकता है जिसका इस्तेमाल SW1 कर रहा है.
  • SW2, उस कैश मेमोरी के कॉन्टेंट में बदलाव कर सकता है जिसका इस्तेमाल SW1 कर रहा है. इससे SW1, ऐसी एसेट के साथ जवाब दे सकता है जिनकी पेज को ज़रूरत नहीं है.

skipWaiting को स्किप करें

इंस्टॉल होने के बाद, पेज को कंट्रोल करने के लिए, सर्विस वर्कर skipWaiting() के जोखिम भरे तरीके का भी इस्तेमाल कर सकता है. आम तौर पर, ऐसा करना अच्छा नहीं होता. ऐसा सिर्फ़ तब किया जा सकता है, जब आपको जान-बूझकर किसी गड़बड़ी वाले सेवा वर्कर को बदलना हो. हो सकता है कि नया सेवा वर्कर, अपडेट किए गए ऐसे रिसॉर्स का इस्तेमाल कर रहा हो जिनकी मौजूदा पेज को ज़रूरत नहीं है. इस वजह से, गड़बड़ियां और बग हो सकते हैं.

खाता खाली करना

अपने सेवा वर्कर को एक-दूसरे से अलग रखने के लिए, यह पक्का करें कि वे अलग-अलग कैश मेमोरी का इस्तेमाल करें. ऐसा करने का सबसे आसान तरीका, कैश मेमोरी में सेव किए गए उन नामों का वर्शन बनाना है जिनका इस्तेमाल किया जाता है.

const version = 1;
const assetCacheName = `assets-${version}`;

self.addEventListener("install", event => {
  caches.open(assetCacheName).then(cache => {
    // confidently do stuff with your very own cache
  });
});

नया सर्विस वर्कर डिप्लॉय करने पर, आपको version को बंप करना होगा, ताकि वह पिछले सर्विस वर्कर से पूरी तरह अलग कैश मेमोरी का इस्तेमाल करके, अपनी ज़रूरत के हिसाब से काम कर सके.

कैश मेमोरी का विज़ुअलाइज़ेशन

एंड क्लीन

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

caches.match() तरीका, किसी भी कैश मेमोरी से मैच होने वाले आइटम को वापस पाने के लिए, अक्सर इस्तेमाल किया जाने वाला शॉर्टकट है. हालांकि, यह कैश मेमोरी को उसी क्रम में दोहराता है जिस क्रम में उन्हें बनाया गया था. मान लें कि आपके पास दो अलग-अलग कैश मेमोरी—assets-1 और assets-2 में, स्क्रिप्ट फ़ाइल app.js के दो वर्शन हैं. आपके पेज को assets-2 में सेव की गई नई स्क्रिप्ट की ज़रूरत है. हालांकि, अगर आपने पुराना कैश मेमोरी मिटाया नहीं है, तो caches.match('app.js'), assets-1 से पुराना पेज दिखाएगा. इससे आपकी साइट पर आने वाले लोगों को समस्या हो सकती है.

पिछले सेवा वर्कर के बाद, सिर्फ़ उस कैश मेमोरी को मिटाना ज़रूरी है जिसकी ज़रूरत नए सेवा वर्कर को नहीं है:

const version = 2;
const assetCacheName = `assets-${version}`;

self.addEventListener("activate", event => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheName !== assetCacheName){
            return caches.delete(cacheName);
          }
        });
      );
    });
  );
});

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

सर्विस वर्कर के बारे में सोच

सेवा देने वाले लोगों के बारे में सोचते समय सही मानसिकता अपनाने से, आपको भरोसे के साथ अपना कारोबार बनाने में मदद मिलेगी. इनका इस्तेमाल करने के बाद, आपको अपने उपयोगकर्ताओं के लिए बेहतरीन अनुभव देने में मदद मिलेगी.

अगर आपको कोई गेम खेलकर यह सब समझना है, तो आपके पास एक मौका है! Service Workies खेलें. इसमें आपको ऑफ़लाइन काम करने वाले ऐप्लिकेशन को खत्म करने के लिए, सेवा वर्कर के काम करने के तरीके के बारे में पता चलेगा.