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

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

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

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

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

पहले जैसा ही है, लेकिन अलग है

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

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

नई लेयर

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

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

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

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

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

दमदार, लेकिन सीमित नतीजों के लिए

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

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

  • 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, लगातार कर रहा है.
  • SW1, कैश मेमोरी में मौजूद उस कॉन्टेंट में बदलाव कर सकता है जिसका इस्तेमाल 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);
          }
        });
      );
    });
  );
});

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

सर्विस वर्कर वाली सोच

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

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