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

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

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

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

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

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

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

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

नई लेयर

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

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

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

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

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

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

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

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

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

  • localStorage
  • DOM
  • विंडो

अच्छी बात यह है कि आपका पेज, अपने सेवा वर्कर के साथ कई तरीकों से कम्यूनिकेट कर सकता है. इनमें डायरेक्ट 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) के बंद होने का इंतज़ार करना पड़ता है.

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

इंस्टॉल करते समय, 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 खेलें. इसमें आपको ऑफ़लाइन काम करने वाले ऐप्लिकेशन को खत्म करने के लिए, सेवा वर्कर के काम करने के तरीके के बारे में पता चलेगा.