डिफ़ॉल्ट रूप से, फ़्रेश सर्विस वर्कर

जेफ़ पॉस्निक
जेफ़ पॉस्निक

tl;dr

Chrome 68 से, सर्विस वर्कर स्क्रिप्ट के अपडेट की जांच करने वाले एचटीटीपी अनुरोध, डिफ़ॉल्ट रूप से एचटीटीपी कैश से पूरी नहीं होंगे. यह सामान्य डेवलपर से जुड़ी आम समस्याओं के लिए काम करता है. इसमें आपके सर्विस वर्कर स्क्रिप्ट पर अनजाने में Cache-Control हेडर सेट करने पर, अपडेट मिलने में देरी हो सकती है.

अगर आपने अपनी /service-worker.js स्क्रिप्ट को Cache-Control: max-age=0 के साथ सर्व करके, एचटीटीपी कैश मेमोरी में सेव करने की सुविधा से पहले ही ऑप्ट-आउट कर लिया है, तो आपको उस नए डिफ़ॉल्ट तरीके से कोई बदलाव नहीं दिखेगा.

इसके अलावा, Chrome 78 से, बाइट के लिए बाइट की तुलना, importScripts() के ज़रिए सर्विस वर्कर में लोड की गई स्क्रिप्ट पर लागू होगी. इंपोर्ट की गई स्क्रिप्ट में किया गया कोई भी बदलाव सर्विस वर्कर अपडेट फ़्लो को ट्रिगर करेगा. यह ठीक उसी तरह होगा, जैसे टॉप-लेवल सर्विस वर्कर में किया गया बदलाव.

बैकग्राउंड

हर बार जब आप सर्विस वर्कर के दायरे में आने वाले किसी नए पेज पर नेविगेट करते हैं, JavaScript से registration.update() को साफ़ तौर पर कॉल करते हैं या जब कोई सर्विस वर्कर push या sync इवेंट के ज़रिए "चालू" होता है, तो ब्राउज़र, सर्विस वर्कर स्क्रिप्ट के अपडेट देखने के लिए, navigator.serviceWorker.register() कॉल को पास किए गए JavaScript रिसॉर्स के लिए अनुरोध करेगा.

इस लेख में, मान लेते हैं कि इसका यूआरएल /service-worker.js है और इसमें importScripts() को किया गया एक ही कॉल शामिल है, जो सर्विस वर्कर के अंदर चलने वाले अतिरिक्त कोड को लोड करता है:

// Inside our /service-worker.js file:
importScripts('path/to/import.js');

// Other top-level code goes here.

क्या बदलाव होने वाले हैं?

Chrome 68 से पहले, /service-worker.js के लिए अपडेट का अनुरोध एचटीटीपी कैश के ज़रिए किया जाता था (जैसा कि ज़्यादातर फ़ेच होते हैं). इसका मतलब है कि अगर स्क्रिप्ट को मूल रूप से Cache-Control: max-age=600 के साथ भेजा गया था, तो अगले 600 सेकंड (10 मिनट) में होने वाले अपडेट, नेटवर्क में नहीं जाएंगे. इससे, हो सकता है कि उपयोगकर्ता को सर्विस वर्कर का सबसे अप-टू-डेट वर्शन न मिले. हालांकि, अगर max-age 86,400 (24 घंटे) से ज़्यादा था, तो इसे 86,400 की तरह ही माना जाएगा, ताकि उपयोगकर्ता हमेशा किसी खास वर्शन का इस्तेमाल न कर पाएं.

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

updateViaCache

डेवलपर अब navigator.serviceWorker.register() को कॉल करते समय एक नया विकल्प पास कर सकते हैं: updateViaCache पैरामीटर. इसके लिए, इन तीन वैल्यू में से कोई एक होनी चाहिए: 'imports', 'all' या 'none'.

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

  • अगर नीति को 'imports' पर सेट किया जाता है, तो /service-worker.js स्क्रिप्ट के अपडेट की जांच करते समय एचटीटीपी कैश मेमोरी से कभी भी जानकारी नहीं ली जाएगी. हालांकि, इंपोर्ट की गई स्क्रिप्ट (हमारे उदाहरण में path/to/import.js) को फ़ेच करते समय, इससे संपर्क किया जाएगा. यह डिफ़ॉल्ट है और यह Chrome 68 से शुरू होने वाले व्यवहार से मेल खाता है.

  • अगर इस नीति को 'all' पर सेट किया जाता है, तो एचटीटीपी कैश मेमोरी को टॉप-लेवल की /service-worker.js स्क्रिप्ट और path/to/import.js जैसे सर्विस वर्कर के अंदर इंपोर्ट की गई स्क्रिप्ट, दोनों के लिए अनुरोध करते समय सलाह दी जाएगी. यह विकल्प, Chrome 68 से पहले के वर्शन में ही काम करता है.

  • अगर इस नीति को 'none' पर सेट किया जाता है, तो टॉप-लेवल /service-worker.js या किसी भी इंपोर्ट की गई स्क्रिप्ट, जैसे कि काल्पनिकpath/to/import.js के लिए अनुरोध करते समय एचटीटीपी कैश से सलाह नहीं ली जाएगी.

उदाहरण के लिए, नीचे दिया गया कोड एक सर्विस वर्कर रजिस्टर करेगा. साथ ही, यह पक्का करेगा कि /service-worker.js स्क्रिप्ट या /service-worker.js में importScripts() के ज़रिए रेफ़र की गई किसी भी स्क्रिप्ट के अपडेट की जांच करते समय एचटीटीपी कैश से कभी मदद न ली जाए:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js', {
    updateViaCache: 'none',
    // Optionally, set 'scope' here, if needed.
  });
}

इंपोर्ट की गई स्क्रिप्ट के अपडेट की जांच करता है

Chrome 78 से पहले, importScripts() से लोड की गई सभी सर्विस वर्कर स्क्रिप्ट को सिर्फ़ एक बार (updateViaCache कॉन्फ़िगरेशन पर निर्भर करते हुए, एचटीटीपी कैश मेमोरी या नेटवर्क से जांच करके) वापस लाया जाएगा. डेटा वापस पाने के बाद, उसे ब्राउज़र के अंदर ही स्टोर किया जाएगा और उसे कभी वापस नहीं लाया जाएगा.

पहले से इंस्टॉल किए गए सर्विस वर्कर को किसी इंपोर्ट की गई स्क्रिप्ट में बदलाव करने के लिए मजबूर करने का एक ही तरीका है, स्क्रिप्ट का यूआरएल बदलना. आम तौर पर, इसके लिए सेमर वैल्यू (जैसे, importScripts('https://example.com/v1.1.0/index.js')) को जोड़ा जाता है या कॉन्टेंट का हैश शामिल किया जाता है (जैसे कि importScripts('https://example.com/index.abcd1234.js')). इंपोर्ट किए गए यूआरएल को बदलने का खराब असर यह होता है कि सर्विस वर्कर स्क्रिप्ट के कॉन्टेंट में बदलाव हो जाता है.

Chrome 78 से शुरू होकर, जब भी किसी टॉप-लेवल सर्विस वर्कर फ़ाइल के लिए अपडेट की जांच की जाती है, तो यह जांच एक ही समय पर की जाती है. इससे यह पता लगाया जाता है कि इंपोर्ट की गई किसी स्क्रिप्ट की सामग्री बदली है या नहीं. इस्तेमाल किए गए Cache-Control हेडर के आधार पर, इंपोर्ट की गई स्क्रिप्ट की ये जांच एचटीटीपी कैश मेमोरी से पूरी हो सकती हैं. ऐसा तब होता है, जब updateViaCache को 'all' या 'imports' (जो डिफ़ॉल्ट वैल्यू है) पर सेट किया गया हो. इसके अलावा, अगर updateViaCache को 'none' पर सेट किया गया है, तो जांच सीधे नेटवर्क पर जा सकती है.

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

Chrome 78 का व्यवहार, Firefox 56 में कई साल पहले लागू किए गए तरीके से मेल खाता है. Safari पहले ही इस व्यवहार को लागू कर देता है.

डेवलपर को क्या करना होगा?

अगर आपने अपनी /service-worker.js स्क्रिप्ट को Cache-Control: max-age=0 (या इससे मिलती-जुलती वैल्यू) के साथ सर्व करके, एचटीटीपी कैश मेमोरी में सेव करने की सुविधा से असरदार तरीके से ऑप्ट-आउट किया है, तो आपको इस नए डिफ़ॉल्ट व्यवहार की वजह से कोई बदलाव नहीं दिखेगा.

अगर अपनी /service-worker.js स्क्रिप्ट को एचटीटीपी कैश मेमोरी में चालू करके दिखाया जाता है, तो जान-बूझकर या इसलिए यह क्योंकि यह सिर्फ़ आपके होस्टिंग एनवायरमेंट के लिए डिफ़ॉल्ट है, आपको अपने सर्वर के लिए /service-worker.js के लिए अतिरिक्त एचटीटीपी अनुरोधों की संख्या में बढ़ोतरी दिख सकती है. ये ऐसे अनुरोध होते हैं जिनका इस्तेमाल एचटीटीपी कैश मेमोरी से किया जाता है. अगर आपको अपने /service-worker.js को अपडेट करने के लिए, Cache-Control हेडर वैल्यू को अनुमति देनी जारी रखनी है, तो आपको अपने सर्विस वर्कर को रजिस्टर करते समय, साफ़ तौर पर updateViaCache: 'all' सेट करना शुरू करना होगा.

यह देखते हुए कि ब्राउज़र के पुराने वर्शन का इस्तेमाल करने वाले बहुत सारे उपयोगकर्ता हो सकते हैं, फिर भी सर्विस वर्कर स्क्रिप्ट पर Cache-Control: max-age=0 एचटीटीपी हेडर सेट करना जारी रखना बेहतर होता है, भले ही नए ब्राउज़र इन्हें अनदेखा कर सकते हैं.

डेवलपर इस अवसर का इस्तेमाल यह तय करने के लिए कर सकते हैं कि वे अपनी इंपोर्ट की गई स्क्रिप्ट को, अभी एचटीटीपी कैश मेमोरी से ऑप्ट आउट करना चाहते हैं या नहीं. साथ ही, सही होने पर अपने सर्विस वर्कर रजिस्ट्रेशन में updateViaCache: 'none' जोड़ सकते हैं.

इंपोर्ट की गई स्क्रिप्ट दिखाई जा रही हैं

Chrome 78 और उसके बाद के वर्शन में, डेवलपर को importScripts() से लोड किए गए रिसॉर्स के लिए, आने वाले एचटीटीपी अनुरोध ज़्यादा दिख सकते हैं. अब उनकी जांच की जाएगी, ताकि अपडेट उपलब्ध न हों.

अगर आपको अतिरिक्त एचटीटीपी ट्रैफ़िक से बचना है, तो लंबे समय तक चलने वाले Cache-Control हेडर सेट करें. ऐसा उन स्क्रिप्ट को दिखाते समय करें जिनके यूआरएल में वीर या हैश का इस्तेमाल किया गया हो. साथ ही, ये 'imports' के डिफ़ॉल्ट updateViaCache व्यवहार पर निर्भर करें.

इसके अलावा, अगर आप चाहते हैं कि अपनी इंपोर्ट की गई स्क्रिप्ट की नियमित रूप से अपडेट होने के लिए जांच की जाए, तो पक्का करें कि आपने उन्हें Cache-Control: max-age=0 की मदद से पेश किया है या आप updateViaCache: 'none' का इस्तेमाल करते हैं.

इसके बारे में और पढ़ें

जेक आर्किबाल्ड ने, "द सर्विस वर्कर लाइफ़साइकल" और "कैशिंग के सबसे सही तरीके और मैक्स-एज गॉचास" को पढ़ने का सुझाव दिया है. ये उन सभी डेवलपर को पढ़ने का सुझाव देते हैं जो वेब पर कुछ भी डिप्लॉय करते हैं.