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

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

डेव गेडेस
डेव गेड्स

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

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

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

वही, लेकिन अलग

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

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

नई लेयर

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

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

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

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

सर्विस वर्क्स गेम में, हम सर्विस वर्कर के लाइफ़साइकल की कई जानकारी कवर करते हैं. साथ ही, आपको इसके साथ काम करने के बारे में कई तरह की प्रैक्टिस करने का मौका देते हैं.

शक्तिशाली, लेकिन सीमित

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

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

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

  • localStorage
  • DOM
  • विंडो

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

लंबे समय तक जीवित रहे, लेकिन कम समय वाले

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

सर्विस वर्क्स में, हम इस सिद्धांत की कल्पना करते हैं. कोलोहे (सेवा देने वाले एक दोस्ताना कर्मचारी) अनुरोधों को इंटरसेप्ट और मैनेज करते हैं.

बंद किया गया

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

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.

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

सर्विस वर्कीज़ चैप्टर 3 में, हम अपने बंद किए गए सर्विस वर्कर को ऐसा मानते हैं कि वह जागने तक सभी रंग खो देता है.

रोके गए सर्विस वर्कर का विज़ुअलाइज़ेशन

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

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

किसी दूसरे सर्विस वर्कर की कैश मेमोरी से छेड़छाड़ करना

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

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

'इंतज़ार करना' छोड़ें

सर्विस वर्कर, पेज के इंस्टॉल होते ही उसे कंट्रोल करने के लिए, जोखिम भरे 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() वाला तरीका, अक्सर इस्तेमाल किया जाने वाला शॉर्टकट है. इसका इस्तेमाल किसी भी कैश मेमोरी से, मैच होने वाले किसी आइटम को वापस पाने के लिए किया जाता है. हालांकि, यह कैश मेमोरी में उसी क्रम में फिर से लागू होता है जिस क्रम में उन्हें बनाया गया था. मान लें कि आपके पास किसी स्क्रिप्ट फ़ाइल के दो वर्शन app.js हैं, जो दो अलग-अलग कैश मेमोरी में हैं—assets-1 और assets-2. आपका पेज 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);
          }
        });
      );
    });
  );
});

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

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

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

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