तुरंत जवाब पाने के लिए स्ट्रीम करें

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

सर्विस वर्कर का इस्तेमाल करने वाला कोई भी व्यक्ति, आपको बता सकता है कि वे एसिंक्रोनस हैं. ये खास तौर पर, इवेंट के आधार पर बने इंटरफ़ेस पर निर्भर करते हैं, जैसे कि FetchEvent. साथ ही, एसिंक्रोनस ऑपरेशन पूरे होने पर, सिग्नल देने के लिए प्रॉमिस का इस्तेमाल करते हैं.

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

अपना fetch इवेंट हैंडलर लिखते समय, आम तौर पर respondWith() तरीके को Response या Response के लिए प्रॉमिसfetch()caches.match() अच्छी बात यह है कि इन दोनों तरीकों से बनाए गए Response पहले से ही स्ट्रीम किए जा सकते हैं! बुरी ख़बर यह है कि "मैन्युअल रूप से" बनाए गए Response स्ट्रीम कम से कम अब तक नहीं किए जा सकते. यहीं पर Streams API की जानकारी डाली जाती है.

स्ट्रीम?

स्ट्रीम एक ऐसा डेटा सोर्स है जिसे रखते हुए बनाया और उसमें बदलाव किया जा सकता है. यह डेटा के एसिंक्रोनस हिस्सों को पढ़ने या लिखने के लिए इंटरफ़ेस उपलब्ध कराता है. स्ट्रीम का सिर्फ़ एक सबसेट, मेमोरी में किसी भी समय उपलब्ध हो सकता है. फ़िलहाल, हमें ReadableStream में दिलचस्पी है. इसका इस्तेमाल, 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()दाना जारी रखता है, तब तक यह उस स्ट्रीम से डेटा पढ़ते रहेगा. सर्विस वर्कर से पेज को मिलने वाला रिस्पॉन्स असल में एसिंक्रोनस होता है. साथ ही, स्ट्रीम को भरने पर हमारा पूरा कंट्रोल होता है!

असल दुनिया में इस्तेमाल

आपने देखा होगा कि पिछले उदाहरण में कुछ प्लेसहोल्डर /* your data here */ टिप्पणियां थीं. साथ ही, यह लागू करने के बारे में सही जानकारी नहीं देता था. तो, असली दुनिया का उदाहरण कैसा दिखेगा?

जेक आर्किबाल्ड (यह कोई अजीब बात नहीं है!) के पास, स्ट्रीम का इस्तेमाल करके, कैश मेमोरी में सेव किए गए कई एचटीएमएल स्निपेट से एचटीएमएल रिस्पॉन्स को एक साथ जोड़ने के लिए स्ट्रीम इस्तेमाल करने का एक बेहतरीन उदाहरण है. इसमें fetch() से स्ट्रीम किया गया "लाइव" डेटा भी शामिल है. इस मामले में, उसके ब्लॉग का कॉन्टेंट

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

स्ट्रीम? या ऐप शेल?

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

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

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

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

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

अलग-अलग स्ट्रीम के बारे में ज़्यादा जानें

अगर आप अपनी ऐसी स्ट्रीम बना रहे हैं जिसे आसानी से पढ़ा जा सकता है, तो हो सकता है कि controller.enqueue() को धीरे-धीरे कॉल करना काफ़ी या कुशल न हो. जेक ने कुछ जानकारी दी है. इसमें बताया गया है कि किस तरह start(), pull(), और cancel() तरीकों को एक साथ इस्तेमाल करके, एक ऐसी डेटा स्ट्रीम बनाई जा सकती है जो आपके इस्तेमाल के उदाहरण के हिसाब से सही हो.

जिन लोगों को ज़्यादा जानकारी चाहिए वे स्ट्रीम की खास बातों के बारे में जान सकते हैं.

इनके साथ काम करता है

किसी सर्विस वर्कर के अंदर, ReadableStream का इस्तेमाल करके Response ऑब्जेक्ट को बनाने की सुविधा देता है, क्योंकि इसके सोर्स को Chrome 52 में जोड़ा गया था.

Firefox का सर्विस वर्कर लागू करने पर, अब भी ReadableStream से मिलने वाले रिस्पॉन्स काम नहीं करते. हालांकि, Streams API से जुड़ी ट्रैकिंग में गड़बड़ी के बारे में बताया गया है, जिसे फ़ॉलो किया जा सकता है.

Edge में Streams API सहायता के साथ-साथ, सर्विस वर्कर सहायता की प्रोग्रेस को Microsoft के प्लैटफ़ॉर्म स्टेटस पेज पर ट्रैक किया जा सकता है.