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

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

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

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

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

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

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

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

यहां कस्टम डिक्शनरी, डेल्टा कंप्रेशन नाम की प्रोसेस का इस्तेमाल करके काम आ सकती है. इसमें किसी संसाधन के पुराने वर्शन की डिक्शनरी का इस्तेमाल करके, बाद के वर्शन को कंप्रेस किया जा सकता है. पिछले उदाहरण का इस्तेमाल करते हुए, अगर आपने डिक्शनरी के तौर पर 1.7.9 का इस्तेमाल करके Angular के वर्शन 1.8.3 को कंप्रेस किया है, तो आउटपुट 4 KiB से ज़्यादा होगा. यह करीब 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 और सीएसएस फ़ाइलें, कंप्रेस किए जा सकने वाले स्टैटिक पेज रिसॉर्स के आम उदाहरण हैं. आम तौर पर, इन संसाधनों को कैश मेमोरी में सेव करने के लिए कई तरीकों से वर्शन बनाया जाता है. कभी-कभी इन्हें फ़ाइल नाम (जैसे कि 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 में भेजने के लिए एक इंटरफ़ेस मिलता है. यह शब्दकोश की मदद से कंप्रेस करने के साथ काम करता है. यहां कुछ बंडलर दिए गए हैं जो शब्दकोश का इस्तेमाल करने की सुविधा देते हैं:

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

इसे आज़माकर देखें!

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

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

नतीजा

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