शेयर किए गए डिक्शनरी की मदद से, कंप्रेस करने की क्षमता को बेहतर बनाएं

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

हालांकि, gzip अपने-आप काफ़ी असरदार है, लेकिन हाल के सालों में वेब पर डेटा कंप्रेस करने की सुविधा को और बेहतर बनाया गया है. साल 2016 में, Brotli एल्गोरिदम को Chrome में शामिल किया गया था. इससे, ज़रूरी शर्तें पूरी करने वाले संसाधनों के लिए, बेहतर कंप्रेशन रेशियो मिलता है. साल 2017 के आखिर तक, सभी आधुनिक ब्राउज़र Brotli के साथ काम करने लगे. साथ ही, इसके लिए सर्वर की सहायता भी ज़्यादा से ज़्यादा उपलब्ध होने लगी. हाल ही में, Chrome ने ZStandard कंप्रेसन की सुविधा लॉन्च की है.

हालांकि, हमारा काम यहीं खत्म नहीं होता! Chrome की टीम, शेयर की गई डिक्शनरी को वेब पर इस्तेमाल करने लायक बनाने पर काम कर रही है. ये डिक्शनरी, Brotli और ZStandard, दोनों के लिए ऑरिजिन ट्रायल में उपलब्ध हैं. शेयर की गई डिक्शनरी, Brotli और ZStandard कंप्रेसन के साथ काम कर सकती हैं. इससे, अक्सर अपडेट किया गया कोड शिप करने वाली वेबसाइटों के लिए, कंप्रेशन रेशियो काफ़ी ज़्यादा हो जाता है. साथ ही, कुछ मामलों में 90% या उससे ज़्यादा कंप्रेशन रेशियो भी मिल सकता है. इस पोस्ट में, शेयर की गई डिक्शनरी के काम करने के तरीके के बारे में ज़्यादा जानकारी दी गई है. साथ ही, यह भी बताया गया है कि अपनी वेबसाइट पर Brotli और ZStandard का इस्तेमाल करने के लिए, ऑरिजिन ट्रायल के लिए कैसे रजिस्टर किया जा सकता है.

शेयर की गई डिक्शनरी के बारे में जानकारी

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

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

यहां एक उदाहरण दिया गया है, जिसमें बताया गया है कि कस्टम कंप्रेसन डिक्शनरी कितनी असरदार हो सकती है: मान लें कि आपकी वेबसाइट Angular फ़्रेमवर्क का इस्तेमाल करती है और आपका मौजूदा वर्शन 1.7.9 है. Angular फ़्रेमवर्क का यह वर्शन, अनकंप्रेस किए जाने पर करीब 172 कि॰ब॰ है. Brotli की डिफ़ॉल्ट सेटिंग का इस्तेमाल करके, इस फ़ाइल को कंप्रेस करने पर, इसका साइज़ करीब 53 केबी हो जाता है. इससे, करीब 70% कंप्रेशन रेशियो मिलता है. हालांकि, मान लें कि आपको बाद में Angular 1.8.3 पर अपग्रेड करना है. Angular के इस वर्शन का साइज़, 1.7.9 वर्शन के साइज़ के बराबर है. इसलिए, आपको पिछले वर्शन के जैसे ही कंप्रेस करने का अनुपात मिल सकता है.

यहां डेल्टा कंप्रेसन नाम की प्रोसेस का इस्तेमाल करके, कस्टम डिक्शनरी का इस्तेमाल किया जा सकता है. इस प्रोसेस में, किसी संसाधन के पिछले वर्शन की डिक्शनरी का इस्तेमाल, उसके नए वर्शन को कंप्रेस करने के लिए किया जाता है. पिछले उदाहरण का इस्तेमाल करके, अगर आपने Angular के 1.8.3 वर्शन को डिक्शनरी के तौर पर 1.7.9 वर्शन का इस्तेमाल करके कंप्रेस किया, तो आउटपुट सिर्फ़ 4 केबी से ज़्यादा होगा. इसका मतलब है कि डेटा को लगभग 98% तक कंप्रेस किया गया है. साफ़ तौर पर, कॉम्प्रेसन डिक्शनरी का असर लोडिंग की परफ़ॉर्मेंस पर काफ़ी पड़ सकता है. साथ ही, असली दुनिया के ऐप्लिकेशन में पहले से ही इनका असर देखा जा चुका है!

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

Chrome, शेयर की गई डिक्शनरी के लिए सहायता का विज्ञापन कैसे दिखाता है

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

Accept-Encoding: gzip, br, zstd

इस खास Accept-Encoding हेडर से पता चलता है कि संसाधन का अनुरोध करने वाला ब्राउज़र, gzip, Brotli, और ZStandard कंप्रेसन एल्गोरिदम के साथ काम करता है. इसके बाद, अनुरोध का जवाब देने वाला वेब सर्वर यह तय कर सकता है कि अनुरोध का जवाब देते समय किस एल्गोरिदम का इस्तेमाल करना है.

शेयर की गई डिक्शनरी की सुविधा चालू होने पर और किसी संसाधन के लिए काम की डिक्शनरी उपलब्ध होने पर, Accept-Encoding हेडर में अतिरिक्त टोकन जोड़े जाते हैं. ये टोकन, Brotli के लिए br-d और Zstandard के लिए zstd-d हैं. Chrome में, उपलब्ध किसी शब्दकोश का हैश भी शामिल होगा. इस बारे में अगले लेख में बताया गया है.

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

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

स्टैटिक संसाधनों के लिए, शेयर की गई डिक्शनरी का कंप्रेस किया गया वर्शन

स्टैटिक पेज रिसॉर्स वह होता है जो अनुरोध किए गए यूआरएल के लिए हमेशा एक ही रिस्पॉन्स देता है. छोटे किए जा सकने वाले स्टैटिक पेज के रिसॉर्स के सामान्य उदाहरणों में, JavaScript और CSS फ़ाइलें शामिल हैं. आम तौर पर, इन संसाधनों को कैश मेमोरी में सेव करने के लिए, किसी तरह से वर्शन में बदला जाता है. कभी-कभी, फ़ाइल के नाम में फ़ाइल के कॉन्टेंट का हैश (उदाहरण के लिए, styles.abcd1234.css) या संसाधन की फ़िंगरप्रिंट करने के किसी अन्य तरीके का इस्तेमाल किया जाता है. शेयर की गई डिक्शनरी में मौजूद डेल्टा कंप्रेसन के लिए, इस तरह के संसाधन सबसे सही होते हैं. इसकी वजह यह है कि स्टैटिक संसाधनों को अक्सर लंबे समय तक कैश मेमोरी में सेव किया जाता है और इन्हें समय-समय पर अपडेट किया जाता है.

किसी स्टैटिक रिसॉर्स के लिए, Use-As-Dictionary रिस्पॉन्स हेडर सेट करके, उसके लिए डिक्शनरी तय की जा सकती है. हेडर में कुछ की/वैल्यू पेयर में से किसी एक का इस्तेमाल किया जा सकता है. हालांकि, match ही ज़रूरी है. यह URLPattern सिंटैक्स स्वीकार करता है, जो उस संसाधन पाथ की जानकारी देता है जहां डिक्शनरी का इस्तेमाल किया जाना चाहिए:

Use-As-Dictionary: match="/dist/styles.*.css"

Use-As-Dictionary हेडर को एक ऐसी सुविधा के तौर पर देखें जो किसी रिसॉर्स के आने वाले वर्शन पर लागू होती है. यह वर्शन, उसमें बताए गए पैटर्न से मेल खाते हैं. मान लें कि आपकी वेबसाइट अपनी सभी स्टाइल को एक ही सीएसएस फ़ाइल में शिप करती है. आसानी के लिए, मान लें कि उस रिसॉर्स का पहला वर्शन /dist/styles.v1.css पर मौजूद है और उसे Use-As-Dictionary रिस्पॉन्स हेडर के साथ भेजा जाता है, जिसमें /dist/styles.*.css की match वैल्यू होती है.

कुछ समय बाद, आपने अपनी वेबसाइट की सीएसएस को अपडेट किया और /dist/styles.v2.css पर उसका नया वर्शन शिप किया. पिछले वर्शन के Use-As-Dictionary रिस्पॉन्स हेडर में इस्तेमाल की गई match वैल्यू, इस अनुरोध पर लागू होती है. इसलिए, ब्राउज़र एक Available-Dictionary हेडर भेजेगा. इसमें, स्ट्रक्चर्ड फ़ील्ड के बाइट क्रम के तौर पर कोड में बदली गई डिक्शनरी का हैश शामिल होगा:

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

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

अगर आपकी वेबसाइट के लिए अक्सर नया कोड शिप किया जाता है, तो डेल्टा कंप्रेसन का इस्तेमाल बहुत फ़ायदेमंद हो सकता है. हालांकि, इस प्रोसेस में बदलाव किया जा सकता है. अगर ब्राउज़र यह पता नहीं लगा पाता कि उपयोगकर्ता के ब्राउज़र कैश मेमोरी में कोई डिक्शनरी उपलब्ध है या नहीं, तो वह Accept-Encoding हेडर में अतिरिक्त br-d या zstd-d टोकन की जानकारी नहीं देगा. ऐसे में, कंप्रेस करने का स्टैंडर्ड तरीका लागू होता है.

डाइनैमिक रिसॉर्स के लिए, शेयर की गई डिक्शनरी को कंप्रेस करना

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

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

<link rel="dictionary" href="/dictionary.dat">

जब Chrome को यह <link> एलिमेंट मिलता है, तो पेज के खाली होने पर वह डिक्शनरी को फ़ेच कर सकता है. साथ ही, बैंडविड्थ के इस्तेमाल को कम करने के लिए, वह इसे कम प्राथमिकता पर फ़ेच करता है. डिक्शनरी के रिस्पॉन्स में Use-As-Dictionary हेडर होना चाहिए. साथ ही, यह भी बताया जाना चाहिए कि यह किस डाइनैमिक रिसॉर्स पाथ पर लागू होता है:

Use-As-Dictionary: match="/product/*"

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

बिल्ड के समय स्टैटिक संसाधनों को कंप्रेस करना

अगर आपको बंडलर के बारे में पता है, तो हो सकता है कि आपको उनके लिए उपलब्ध अलग-अलग प्लग इन के बारे में भी पता हो. ये प्लग इन, बिल्ड के समय संसाधनों को कंप्रेस कर सकते हैं और बाद में उन कंप्रेस किए गए संसाधनों को दिखा सकते हैं. उदाहरण के लिए, अनुरोध के समय Apache, पहले से संकुचित किए गए संसाधनों को दिखाने के लिए निर्देशों का इस्तेमाल करने की सुविधा देता है.

कंप्रेस करने की सुविधा वाले ज़्यादातर Node.js-आधारित बंडलर, Node की Zlib लाइब्रेरी का इस्तेमाल करते हैं. Zlib, Brotli और बंडलर के साथ काम करता है. आम तौर पर, बंडलर में एक इंटरफ़ेस होता है, जिसकी मदद से विकल्पों को सीधे Zlib में पास किया जा सकता है. Zlib, डिक्शनरी की मदद से कॉन्टेंट को कंप्रेस करने की सुविधा देता है. यहां कुछ ऐसे बंडलर दिए गए हैं जो डिक्शनरी का इस्तेमाल करते हैं:

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

इसे आज़माएं!

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

  1. अगर आपको शेयर की गई डिक्शनरी के कंप्रेस किए गए वर्शन को खुद आज़माना है, ताकि यह पता चल सके कि यह कैसे काम करता है, तो chrome://flags पेज पर कंप्रेस की गई डिक्शनरी को ट्रांसपोर्ट करने की एक्सपेरिमेंटल सुविधा चालू करें.
  2. अगर आपको अपनी प्रोडक्शन वेबसाइट पर इसे आज़माना है और यह देखना है कि शेयर की गई डिक्शनरी को कंप्रेस करने से, असल उपयोगकर्ताओं को क्या फ़ायदा हो सकता है, तो टोकन पाने के लिए ऑरिजिन ट्रायल के लिए रजिस्टर करें. साथ ही, ऑरिजिन ट्रायल के काम करने का तरीका पढ़ें.

नतीजा

हम वेब पर कॉम्प्रेस करने की टेक्नोलॉजी में हुई इस बड़ी तरक्की से काफ़ी उत्साहित हैं. साथ ही, हम यह जानने के लिए भी उत्साहित हैं कि यह टेक्नोलॉजी, लोगों के हर रोज़ इस्तेमाल होने वाले मौजूदा ऐप्लिकेशन को कितना तेज़ कर सकती है. हमारा सुझाव है कि आप इसे आज़माएं. अगर आपने इसे आज़माया, तो हमें अपने विचारों के बारे में बताएं! अगर आपको कोई गड़बड़ी मिलती है, तो उसे crbug.com पर दर्ज करें. ज़्यादा संसाधनों और टूल के लिए, use-as-dictionary.com पर जाएं. आखिर में, अगर आपको यह जानना है कि यह सुविधा कैसे काम करती है, तो एक्सप्लेनर देखें!