पब्लिश होने की तारीख: 6 मार्च, 2024
डेटा कंप्रेशन, परफ़ॉर्मेंस ऑप्टिमाइज़ेशन की एक ऐसी तकनीक है जिसका इस्तेमाल लंबे समय से किया जा रहा है. इसकी मदद से, ज़रूरी शर्तों को पूरा करने वाले पेज के रिसॉर्स का साइज़ कम किया जा सकता है. कुछ समय पहले तक, वेब सर्वर पर gzip का इस्तेमाल करके, टेक्स्ट पर आधारित पेज के रिसॉर्स को कंप्रेस करना आम बात थी. जैसे, एचटीएमएल, सीएसएस, और JavaScript फ़ाइलें. इसके बाद, इन फ़ाइलों को क्लाइंट को भेजा जाता था, जहां इन्हें डीकंप्रेस किया जा सकता था. इससे, पेज के काम करने के तरीके पर असर डाले बिना, रिसॉर्स तेज़ी से लोड होते हैं.
हालांकि, gzip अपने-आप में काफ़ी असरदार है. इसके बावजूद, हाल के सालों में वेब पर कंप्रेशन में और सुधार हुए हैं. साल 2016 में, Chrome में Brotli एल्गोरिदम शिप किया गया था. इससे ज़रूरी शर्तों को पूरा करने वाले रिसॉर्स के लिए, कंप्रेशन के बेहतर अनुपात मिले. साल 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 की डिक्शनरी का इस्तेमाल करके कंप्रेस किया, तो आउटपुट सिर्फ़ चार केबी से थोड़ा ज़्यादा होगा. इससे, कंप्रेशन का अनुपात करीब 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
Use-As-Dictionary हेडर को एक ऐसे मैकेनिज़्म के तौर पर समझें जो किसी रिसॉर्स के आने वाले वर्शन पर लागू होता है. यह वर्शन, इसमें तय किए गए पैटर्न से मेल खाता है. मान लें कि आपकी वेबसाइट, अपने सभी स्टाइल को एक ही सीएसएस फ़ाइल में शिप करती है. आसान बनाने के लिए, मान लें कि उस रिसॉर्स का पहला वर्शन, /dist/styles.v1.css पर मौजूद है. इसे Use-As-Dictionary रिस्पॉन्स हेडर के साथ भेजा जाता है. इसमें, match की वैल्यू /dist/styles.*.css होती है.
कुछ समय बाद, आपने अपनी वेबसाइट के सीएसएस को अपडेट किया और उसका नया वर्शन शिप किया. यह वर्शन, /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 में पास करने के लिए इंटरफ़ेस उपलब्ध कराते हैं. यह डिक्शनरी की मदद से कंप्रेशन की सुविधा देता है. यहां कुछ ऐसे बंडलर दिए गए हैं जो डिक्शनरी का इस्तेमाल करने की सुविधा देते हैं:
- webpack का
CompressionWebpackPlugin, इसकेcompressionOptionsइंटरफ़ेस के ज़रिए. rollup-plugin-brotlioptionsकॉन्फ़िगरेशन उपलब्ध कराता है. यह सीधे Node.js में Zlib को पास होता है. इसमें डिक्शनरी तय की जा सकती हैं.- esbuild के लिए,
esbuild-plugin-compressतीसरे पक्ष का प्लग-इन भी Node.js में Zlib के विकल्पों का ऐक्सेस देता है.
ध्यान दें कि किसी रिसॉर्स के किसी भी वर्शन के लिए उपलब्ध डिक्शनरी में, रिसॉर्स के किसी भी पिछले वर्शन का इस्तेमाल किया जा सकता है. इसका मतलब है कि आपको उपयोगकर्ता के ट्रैफ़िक का विश्लेषण करना होगा और उसके हिसाब से प्लान बनाना होगा. बैलेंस बनाए रखें और ऐसे रिसॉर्स जनरेट करें जिनसे वापस आने वाले ज़्यादा से ज़्यादा उपयोगकर्ताओं को फ़ायदा मिले. फ़िलहाल, सीडीएन सेवा देने वाली कंपनियां, शेयर की गई डिक्शनरी के कंप्रेशन के साथ एक्सपेरिमेंट कर रही हैं. आम तौर पर इस्तेमाल करने के लिए, फ़िलहाल कोई भी इंप्लीमेंटेशन उपलब्ध नहीं है. हालांकि, हमें उम्मीद है कि आने वाले समय में यह सुविधा उपलब्ध होगी!
इसे आज़माएं!
शेयर की गई डिक्शनरी के कंप्रेशन को, ब्राउज़र की मौजूदा कंप्रेशन सुविधाओं के साथ इंटिग्रेट करने से, उन वेबसाइटों के लिए लोड होने की परफ़ॉर्मेंस को बेहतर बनाया जा सकता है जो अक्सर अपडेट किया गया प्रोडक्शन कोड शिप करती हैं. साथ ही, वापस आने वाले लोगों से उन्हें काफ़ी ट्रैफ़िक मिलता है. अगर आपको शेयर की गई डिक्शनरी के कंप्रेशन को आज़माना है, तो आपके पास दो विकल्प हैं:
- अगर आपको सिर्फ़ शेयर की गई डिक्शनरी के कंप्रेशन को आज़माकर देखना है, ताकि आपको यह पता चल सके कि यह कैसे काम करता है, तो
chrome://flagsपेज पर कंप्रेशन डिक्शनरी ट्रांसपोर्ट की एक्सपेरिमेंटल सुविधा चालू करें. - अगर आपको अपनी प्रोडक्शन वेबसाइट पर इसे आज़माना है और यह देखना है कि शेयर की गई डिक्शनरी के कंप्रेशन से, असल उपयोगकर्ताओं को कैसे फ़ायदा मिल सकता है, तो ऑरिजिन ट्रायल के लिए रजिस्टर करें, ताकि आपको टोकन मिल सके. साथ ही, ऑरिजिन ट्रायल के काम करने के तरीके के बारे में पढ़ें.
नतीजा
हम वेब पर कंप्रेशन टेक्नोलॉजी में हुए इस बड़े बदलाव को लेकर काफ़ी उत्साहित हैं. साथ ही, हमें यह भी उम्मीद है कि इससे, मौजूदा ऐप्लिकेशन पहले से ज़्यादा तेज़ी से काम करेंगे. लोग इन ऐप्लिकेशन का इस्तेमाल हर दिन करते हैं. हमारा सुझाव है कि आप इसे आज़माएं. साथ ही, सबसे अहम बात यह है कि अगर आपको यह सुविधा पसंद आती है, तो हमें अपने सुझाव/राय ज़रूर बताएं! अगर आपको कोई गड़बड़ी मिलती है, तो crbug.com पर उसकी शिकायत करें. ज़्यादा संसाधन और टूल पाने के लिए, use-as-dictionary.com देखें. आखिर में, अगर आपको यह जानना है कि यह सुविधा कैसे काम करती है, तो इसके बारे में जानकारी देने वाला लेख पढ़ें!