सेवा वर्कर का इस्तेमाल करने वाला कोई भी व्यक्ति आपको बता सकता है कि वे पूरी तरह से असाइनोक्रोनस हैं. ये पूरी तरह से इवेंट-आधारित इंटरफ़ेस पर निर्भर होते हैं, जैसे कि FetchEvent
. साथ ही, असाइनमेंट के अलग-अलग क्रम में पूरे होने का सिग्नल देने के लिए, प्रॉमिस का इस्तेमाल करते हैं.
जब बात सेवा वर्कर के फ़ेच इवेंट हैंडलर से मिले जवाबों की आती है, तो डेवलपर के लिए असाइनमेंट के साथ-साथ, असाइनमेंट के बिना भी काम करना उतना ही ज़रूरी है. जवाबों को स्ट्रीम करना सबसे सही तरीका है: इससे, डेटा का पहला हिस्सा उपलब्ध होते ही, ओरिजनल अनुरोध करने वाले पेज को जवाब के साथ काम करना शुरू करने में मदद मिलती है. साथ ही, कॉन्टेंट को धीरे-धीरे दिखाने के लिए, स्ट्रीमिंग के लिए ऑप्टिमाइज़ किए गए पार्सरों का इस्तेमाल किया जा सकता है.
अपना fetch
इवेंट हैंडलर लिखते समय, आम तौर पर respondWith()
विधि को Response
(या Response
के लिए एक वादा) पास किया जाता है, जो आपको fetch()
या caches.match()
के ज़रिए मिलता है. इसके बाद, इसे पूरा कर दिया जाता है. अच्छी बात यह है कि इन दोनों तरीकों से बनाए गए Response
, पहले से ही स्ट्रीम किए जा सकते हैं! बुरी खबर यह है कि "मैन्युअल तरीके से"
बनाए गए
Response
, कम से कम फ़िलहाल स्ट्रीम नहीं किए जा सकते. यहीं पर Streams API काम आता है.
स्ट्रीम?
स्ट्रीम एक ऐसा डेटा सोर्स है जिसे बढ़ते हुए क्रम में बनाया और मैनेज किया जा सकता है. साथ ही, यह डेटा के असाइनोक्रोनस हिस्सों को पढ़ने या लिखने के लिए इंटरफ़ेस उपलब्ध कराता है. किसी भी समय, मेमोरी में इसका सिर्फ़ एक सबसेट उपलब्ध हो सकता है. फ़िलहाल, हम ReadableStream
s में दिलचस्पी रखते हैं. इनका इस्तेमाल, fetchEvent.respondWith()
को पास किए गए Response
ऑब्जेक्ट को बनाने के लिए किया जा सकता है:
self.addEventListener('fetch', event => {
var stream = new ReadableStream({
start(controller) {
if (/* there's more data */) {
controller.enqueue(/* your data here */);
} else {
controller.close();
}
});
});
var response = new Response(stream, {
headers: {'content-type': /* your content-type here */}
});
event.respondWith(response);
});
जिस पेज के अनुरोध से fetch
इवेंट ट्रिगर हुआ है उसे event.respondWith()
का इस्तेमाल करने पर, स्ट्रीमिंग का जवाब मिल जाएगा. साथ ही, जब तक सर्विस वर्कर enqueue()
से अतिरिक्त डेटा enqueue()
करता रहेगा, तब तक वह उस स्ट्रीम से पढ़ता रहेगा. सेवा वर्कर से पेज पर मिलने वाला जवाब, असल में एक साथ नहीं मिलता. साथ ही, स्ट्रीम को भरने पर हमारा पूरा कंट्रोल होता है!
असल दुनिया में इस्तेमाल
आपने शायद देखा होगा कि पिछले उदाहरण में कुछ प्लेसहोल्डर
/* your data here */
टिप्पणियां थीं और लागू करने की असल जानकारी कम थी.
तो असल दुनिया का उदाहरण कैसा दिखेगा?
जैक अर्किबाल्ड (कोई आश्चर्य नहीं!) ने fetch()
के ज़रिए स्ट्रीम किए गए "लाइव" डेटा के साथ-साथ, कैश मेमोरी में सेव किए गए कई एचटीएमएल स्निपेट से एचटीएमएल रिस्पॉन्स को एक साथ जोड़ने के लिए, स्ट्रीम का इस्तेमाल करने का शानदार उदाहरण दिया है. इस मामले में, उनके ब्लॉग का कॉन्टेंट
जैक ने बताया है कि स्ट्रीमिंग रिस्पॉन्स का इस्तेमाल करने का फ़ायदा यह है कि ब्राउज़र, एचटीएमएल को स्ट्रीम करते समय उसे पार्स और रेंडर कर सकता है. इसमें कैश मेमोरी से तुरंत लोड होने वाला शुरुआती हिस्सा भी शामिल है. इसके लिए, उसे पूरे ब्लॉग कॉन्टेंट के फ़ेच होने का इंतज़ार नहीं करना पड़ता. इससे ब्राउज़र की प्रोग्रेसिव एचटीएमएल रेंडरिंग की सुविधाओं का पूरा फ़ायदा मिलता है. इस तरीके से, कुछ इमेज और वीडियो फ़ॉर्मैट जैसे अन्य रिसॉर्स को भी धीरे-धीरे रेंडर किया जा सकता है.
स्ट्रीम? या ऐप्लिकेशन शेल?
वेब ऐप्लिकेशन को बेहतर बनाने के लिए, सेवा वर्कर का इस्तेमाल करने के मौजूदा सबसे सही तरीके, ऐप्लिकेशन शेल + डाइनैमिक कॉन्टेंट मॉडल पर फ़ोकस करते हैं. यह तरीका, आपके वेब ऐप्लिकेशन के "शेल" को तेज़ी से कैश मेमोरी में सेव करने पर निर्भर करता है. शैल, आपके स्ट्रक्चर और लेआउट को दिखाने के लिए ज़रूरी एचटीएमएल, JavaScript, और सीएसएस का कम से कम हिस्सा होता है. इसके बाद, क्लाइंट-साइड अनुरोध की मदद से, हर पेज के लिए ज़रूरी डाइनैमिक कॉन्टेंट लोड किया जाता है.
स्ट्रीम, ऐप्लिकेशन शेल मॉडल का एक विकल्प है. इसमें, जब कोई उपयोगकर्ता किसी नए पेज पर जाता है, तो ब्राउज़र पर एचटीएमएल का पूरा जवाब स्ट्रीम किया जाता है. स्ट्रीम किए गए रिस्पॉन्स में कैश मेमोरी में सेव किए गए रिसॉर्स का इस्तेमाल किया जा सकता है. इसलिए, यह ऑफ़लाइन होने पर भी एचटीएमएल का शुरुआती हिस्सा तुरंत दिखा सकता है! हालांकि, ये रिस्पॉन्स, सर्वर से रेंडर किए गए रिस्पॉन्स बॉडी की तरह ही दिखते हैं. उदाहरण के लिए, अगर आपका वेब ऐप्लिकेशन किसी ऐसे कॉन्टेंट मैनेजमेंट सिस्टम से काम करता है जो एचटीएमएल को सर्वर पर रेंडर करता है, तो वह मॉडल सीधे स्ट्रीमिंग रिस्पॉन्स का इस्तेमाल करता है. साथ ही, टेंप्लेट लॉजिक को आपके सर्वर के बजाय, सेवा वर्कर में दोहराया जाता है. इस वीडियो में दिखाया गया है कि इस उदाहरण के लिए, स्ट्रीम किए गए जवाबों की तेज़ी का फ़ायदा काफ़ी असरदार हो सकता है:
पूरे एचटीएमएल रिस्पॉन्स को स्ट्रीम करने का एक अहम फ़ायदा यह है कि यह वीडियो में सबसे तेज़ विकल्प है. इसकी वजह यह है कि शुरुआती नेविगेशन अनुरोध के दौरान रेंडर किया गया एचटीएमएल, ब्राउज़र के स्ट्रीमिंग एचटीएमएल पार्सर का पूरा फ़ायदा ले सकता है. पेज लोड होने के बाद दस्तावेज़ में डाले गए एचटीएमएल के ऐसे हिस्से, इस ऑप्टिमाइज़ेशन का फ़ायदा नहीं ले सकते. आम तौर पर, ऐप्लिकेशन शेल मॉडल में ऐसा होता है.
इसलिए, अगर आपको सेवा वर्कर लागू करने की योजना बनानी है, तो आपको कौनसा मॉडल अपनाना चाहिए: धीरे-धीरे रेंडर होने वाले स्ट्रीम किए गए जवाब या डायनैमिक कॉन्टेंट के लिए क्लाइंट-साइड अनुरोध के साथ हल्का शेल? इसका जवाब यह है कि यह कई बातों पर निर्भर करता है: आपके पास पहले से कोई ऐसा लागू तरीका है या नहीं जो कॉन्टेंट मैनेजमेंट सिस्टम और कुछ टेंप्लेट पर निर्भर करता है (फ़ायदा: स्ट्रीम); क्या आपको एक बड़े एचटीएमएल पेलोड की उम्मीद है जिसे प्रोग्रेसिव रेंडरिंग से फ़ायदा मिलेगा (फ़ायदा: स्ट्रीम); क्या आपके वेब ऐप्लिकेशन को एक पेज वाले ऐप्लिकेशन के तौर पर सबसे बेहतर तरीके से मॉडल किया गया है (फ़ायदा: ऐप्लिकेशन शेल); और क्या आपको ऐसे मॉडल की ज़रूरत है जो फ़िलहाल कई ब्राउज़र के स्टेबल रिलीज़ पर काम करता हो (फ़ायदा: ऐप्लिकेशन शेल).
हम अभी सेवा वर्कर की मदद से स्ट्रीमिंग रिस्पॉन्स की सुविधा के शुरुआती दौर में हैं. हमें उम्मीद है कि अलग-अलग मॉडल बेहतर होंगे और आम तौर पर इस्तेमाल होने वाले उदाहरणों को ऑटोमेट करने के लिए, ज़्यादा टूल विकसित किए जाएंगे.
स्ट्रीम के बारे में ज़्यादा जानकारी
अगर आपको अपनी पढ़ी जा सकने वाली स्ट्रीम बनानी हैं, तो हो सकता है कि controller.enqueue()
को बिना किसी प्लान के कॉल करना, न तो काफ़ी हो और न ही कारगर. जैक ने start()
, pull()
, और cancel()
तरीकों का इस्तेमाल करके, आपके इस्तेमाल के उदाहरण के हिसाब से डेटा स्ट्रीम बनाने के बारे में ज़्यादा जानकारी दी है.
अगर आपको ज़्यादा जानकारी चाहिए, तो स्ट्रीम के स्पेसिफ़िकेशन देखें.
इनके साथ काम करता है
Chrome 52 में, सोर्स के तौर पर ReadableStream
का इस्तेमाल करके, सेवा वर्कर के अंदर Response
ऑब्जेक्ट बनाने की सुविधा जोड़ी गई थी.
फ़ायरफ़ॉक्स में सेवा वर्कर लागू करने की सुविधा, अब तक ReadableStream
के साथ काम नहीं करती. हालांकि, Streams API के साथ काम करने के लिए, एक काम का ट्रैकिंग बग मौजूद है.
Edge में, बिना प्रीफ़िक्स वाले Streams API के साथ काम करने की सुविधा और सेवा वर्कर के साथ काम करने की सुविधा के साथ-साथ, इस सुविधा के पूरी तरह से काम करने की प्रोग्रेस को Microsoft के प्लैटफ़ॉर्म स्टेटस पेज पर ट्रैक किया जा सकता है.