tl;dr
Chrome 68 से, सेवा वर्कर स्क्रिप्ट के अपडेट की जांच करने वाले एचटीटीपी अनुरोधों को डिफ़ॉल्ट रूप से एचटीटीपी कैश मेमोरी से पूरा नहीं किया जाएगा. यह डेवलपर की एक आम समस्या को हल करता है. इसमें, आपकी सेवा वर्कर स्क्रिप्ट पर Cache-Control
हेडर को गलती से सेट करने पर, अपडेट में देरी हो सकती है.
अगर आपने /service-worker.js
स्क्रिप्ट को Cache-Control: max-age=0
के साथ दिखाकर, एचटीटीपी कैश मेमोरी से पहले ही ऑप्ट-आउट कर लिया है, तो आपको डिफ़ॉल्ट तौर पर लागू होने वाली नई सुविधा की वजह से कोई बदलाव नहीं दिखेगा.
इसके अलावा, Chrome 78 से, बाइट-बाइट की तुलना, importScripts()
के ज़रिए सेवा वर्कर में लोड की गई स्क्रिप्ट पर लागू की जाएगी.
इंपोर्ट की गई स्क्रिप्ट में किया गया कोई भी बदलाव, सेवा वर्कर अपडेट फ़्लो को ट्रिगर करेगा. ठीक उसी तरह जैसे टॉप-लेवल सेवा वर्कर में किया गया बदलाव ट्रिगर करता है.
बैकग्राउंड
जब भी किसी ऐसे नए पेज पर नेविगेट किया जाता है जो सेवा वर्कर के दायरे में आता है, तो JavaScript से साफ़ तौर पर registration.update()
को कॉल करें. इसके अलावा, जब किसी सेवा वर्कर को push
या sync
इवेंट की मदद से "जागृत" किया जाता है, तो ब्राउज़र, सेवा वर्कर स्क्रिप्ट में अपडेट देखने के लिए, उस JavaScript संसाधन का अनुरोध करेगा जिसे मूल रूप से navigator.serviceWorker.register()
कॉल में पास किया गया था.
इस लेख के लिए, मान लें कि इसका यूआरएल /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
86400 (24 घंटे) से ज़्यादा था, तो इसे 86400 माना जाएगा, ताकि उपयोगकर्ता किसी खास वर्शन पर हमेशा के लिए फंस न जाएं.
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 से पहले के वर्शन में Chrome के काम करने के तरीके से मेल खाता है.'none'
पर सेट होने पर, टॉप-लेवल/service-worker.js
या किसी भी इंपोर्ट की गई स्क्रिप्ट के लिए अनुरोध करते समय, एचटीटीपी कैश मेमोरी का इस्तेमाल नहीं किया जाएगा. जैसे, hipotéticopath/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
कॉन्फ़िगरेशन के हिसाब से, पहले एचटीटीपी कैश मेमोरी में या फिर नेटवर्क से जांच की जाती थी. पहली बार इकट्ठा करने के बाद, ब्राउज़र उसे अपने-आप सेव कर लेगा और फिर से फ़ेच नहीं करेगा.
पहले से इंस्टॉल किए गए सेवा वर्कर को, इंपोर्ट की गई स्क्रिप्ट में किए गए बदलावों को लागू करने के लिए मजबूर करने का एक ही तरीका था. इसके लिए, स्क्रिप्ट का यूआरएल बदलना होता था. आम तौर पर, semver वैल्यू (उदाहरण के लिए, 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 में Firefox के कई साल पहले लागू किए गए व्यवहार से मेल खाता है. Safari में भी यह सुविधा पहले से ही मौजूद है.
डेवलपर को क्या करना होगा?
अगर आपने अपनी /service-worker.js
स्क्रिप्ट को Cache-Control: max-age=0
(या मिलती-जुलती वैल्यू) के साथ दिखाकर, एचटीटीपी कैश मेमोरी से ऑप्ट-आउट कर दिया है, तो आपको डिफ़ॉल्ट तौर पर लागू होने वाले नए व्यवहार की वजह से कोई बदलाव नहीं दिखेगा.
अगर आपने एचटीटीपी कैश मेमोरी चालू करके अपनी /service-worker.js
स्क्रिप्ट को दिखाया है, तो हो सकता है कि आपको अपने सर्वर पर /service-worker.js
के लिए, अतिरिक्त एचटीटीपी अनुरोधों की संख्या बढ़ती हुई दिखे. ऐसा इसलिए होता है, क्योंकि एचटीटीपी कैश मेमोरी की मदद से ये अनुरोध पहले ही पूरे हो जाते थे. अगर आपको Cache-Control
हेडर वैल्यू को /service-worker.js
के अपडेट होने की फ़्रीक्वेंसी पर असर डालने की अनुमति देनी है, तो आपको अपने सेवा वर्कर को रजिस्टर करते समय, updateViaCache: 'all'
को साफ़ तौर पर सेट करना होगा.
पुराने ब्राउज़र वर्शन का इस्तेमाल करने वाले उपयोगकर्ताओं की संख्या काफ़ी हो सकती है. इसलिए, सेवा वर्कर स्क्रिप्ट पर Cache-Control: max-age=0
एचटीटीपी हेडर सेट करना अब भी एक अच्छा विचार है. भले ही, नए ब्राउज़र इन हेडर को अनदेखा कर सकते हैं.
डेवलपर इस मौके का इस्तेमाल करके यह तय कर सकते हैं कि उन्हें इंपोर्ट की गई स्क्रिप्ट को एचटीटीपी कैश मेमोरी से अभी हटाना है या नहीं. साथ ही, अगर ज़रूरी हो, तो अपने सेवा वर्कर रजिस्ट्रेशन में updateViaCache: 'none'
जोड़ें.
इंपोर्ट की गई स्क्रिप्ट दिखाना
Chrome 78 से, डेवलपर को importScripts()
के ज़रिए लोड किए गए संसाधनों के लिए, इनकमिंग एचटीटीपी अनुरोध ज़्यादा दिख सकते हैं. इसकी वजह यह है कि अब इन संसाधनों के अपडेट की जांच की जाएगी.
अगर आपको इस अतिरिक्त एचटीटीपी ट्रैफ़िक से बचना है, तो लंबे समय तक काम करने वाले Cache-Control
हेडर सेट करें. ऐसा तब करें, जब ऐसी स्क्रिप्ट दिखाई जा रही हों जिनके यूआरएल में semver या हैश शामिल हों. साथ ही, 'imports'
के डिफ़ॉल्ट updateViaCache
व्यवहार पर भरोसा करें.
इसके अलावा, अगर आपको अपनी इंपोर्ट की गई स्क्रिप्ट में होने वाले बार-बार अपडेट की जांच करनी है, तो पक्का करें कि आप उन्हें Cache-Control: max-age=0
के साथ दिखाएं या updateViaCache: 'none'
का इस्तेमाल करें.
इसके बारे में और पढ़ें
वेब पर कुछ भी डिप्लॉय करने वाले सभी डेवलपर को, जैक आर्किबाल्ड की लिखी "सेवा वर्कर का लाइफ़साइकल" और "कैश मेमोरी का इस्तेमाल करने के सबसे सही तरीके और max-age से जुड़ी समस्याएं" लेख पढ़ने का सुझाव दिया जाता है.