उपयोगकर्ताओं के हिसाब से क्लाइंट संकेतों के हिसाब से बदलाव करना

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

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

कॉन्टेंट के लिए बातचीत करना

क्लाइंट हिंट, कॉन्टेंट के लिए बातचीत का एक और तरीका है. इसका मतलब है कि ब्राउज़र के अनुरोध हेडर के आधार पर, कॉन्टेंट के जवाबों में बदलाव करना.

कॉन्टेंट के लिए बातचीत करने का एक उदाहरण, Accept अनुरोध हेडर है. इससे पता चलता है कि ब्राउज़र किस तरह के कॉन्टेंट को समझता है. इससे, सर्वर जवाब के लिए बातचीत कर सकता है. इमेज के अनुरोधों के लिए, Chrome के Accept हेडर का कॉन्टेंट यह है:

Accept: image/webp,image/apng,image/*,*/*;q=0.8

सभी ब्राउज़र पर JPEG, PNG, और GIF जैसे इमेज फ़ॉर्मैट काम करते हैं. हालांकि, इस मामले में 'स्वीकार करें' से पता चलता है कि ब्राउज़र पर WebP और APNG भी काम करते हैं. इस जानकारी का इस्तेमाल करके, हम हर ब्राउज़र के लिए सबसे सही इमेज टाइप तय कर सकते हैं:

<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;

// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">

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

ऑप्ट इन करना

Accept हेडर के उलट, क्लाइंट हिंट अपने-आप नहीं दिखते. हालांकि, Save-Data के मामले में ऐसा होता है. इस बारे में हम बाद में बात करेंगे. अनुरोध हेडर को कम से कम रखने के लिए, आपको यह तय करना होगा कि उपयोगकर्ता किसी संसाधन का अनुरोध करने पर, आपको कौनसे क्लाइंट हिंट चाहिए. इसके लिए, आपको Accept-CH हेडर भेजना होगा:

Accept-CH: Viewport-Width, Downlink

Accept-CH की वैल्यू, अनुरोध किए गए उन हिंट की सूची होती है जिन्हें कॉमा लगाकर अलग किया गया हो. साइट, रिसॉर्स के अगले अनुरोध के नतीजे तय करने के लिए इनका इस्तेमाल करेगी. जब क्लाइंट इस हेडर को पढ़ता है, तो उसे यह बताया जाता है कि “इस साइट को Viewport-Width और Downlink क्लाइंट हिंट चाहिए.” खास हिंट के बारे में चिंता न करें. हम इनके बारे में थोड़ी देर में बताएंगे.

इन ऑप्ट-इन हेडर को किसी भी बैक-एंड भाषा में सेट किया जा सकता है. उदाहरण के लिए, PHP के header फ़ंक्शन का इस्तेमाल किया जा सकता है. <meta> टैग पर, http-equiv एट्रिब्यूट के साथ इन ऑप्ट-इन हेडर को भी सेट किया जा सकता है:

<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />

क्लाइंट के सभी संकेत!

क्लाइंट हिंट से इनमें से किसी एक चीज़ के बारे में पता चलता है: आपके उपयोगकर्ताओं का इस्तेमाल किया जाने वाला डिवाइस और आपकी साइट को ऐक्सेस करने के लिए इस्तेमाल किया जा रहा नेटवर्क. चलिए, उपलब्ध सभी संकेत देखें.

डिवाइस के लिए हिंट

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

इस सूची पर जाने से पहले, स्क्रीन और मीडिया रिज़ॉल्यूशन के बारे में बताने के लिए इस्तेमाल किए जाने वाले कुछ मुख्य शब्दों के बारे में जानना मददगार हो सकता है:

इंट्रिन्सिक साइज़: किसी मीडिया रिसॉर्स के असल डाइमेंशन. उदाहरण के लिए, अगर आपने Photoshop में कोई इमेज खोली है, तो इमेज के साइज़ वाले डायलॉग में दिखाए गए डाइमेंशन से, इमेज के असल साइज़ के बारे में पता चलता है.

डेंसिटी में बदलाव के बाद का मूल साइज़: पिक्सल डेंसिटी में बदलाव करने के बाद, मीडिया रिसॉर्स के डाइमेंशन. यह इमेज के असल साइज़ को डिवाइस के पिक्सल रेशियो से divide किया जाता है. उदाहरण के लिए, इस मार्कअप को देखें:

<img
  src="whats-up-1x.png"
  srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
  alt="I'm that image you wanted."
/>

मान लें कि इस मामले में 1x इमेज का मूल साइज़ 320x240 है और 2x इमेज का मूल साइज़ 640x480 है. अगर इस मार्कअप को किसी ऐसे डिवाइस पर इंस्टॉल किए गए क्लाइंट से पार्स किया जाता है जिसकी स्क्रीन डिवाइस पिक्सल रेशियो 2 है (जैसे, रेटिना स्क्रीन), तो 2x इमेज का अनुरोध किया जाता है. 2x इमेज का घनत्व के हिसाब से सही किया गया मूल साइज़ 320x240 है, क्योंकि 640x480 को दो से भाग देने पर 320x240 मिलता है.

बाहरी साइज़: सीएसएस और लेआउट के अन्य फ़ैक्टर (जैसे, width और height एट्रिब्यूट) लागू होने के बाद, मीडिया रिसॉर्स का साइज़. मान लें कि आपके पास एक <img> एलिमेंट है, जो 320x240 के घनत्व में बदलाव किए गए मूल साइज़ वाली इमेज को लोड करता है. हालांकि, इसमें सीएसएस width और height प्रॉपर्टी भी हैं, जिन पर क्रमशः 256px और 192px वैल्यू लागू की गई हैं. इस उदाहरण में, <img> एलिमेंट का एक्सट्रिंसिक साइज़ 256x192 हो जाता है.

इंट्रिन्सिक साइज़ बनाम एक्सट्रिन्सिक साइज़ का उदाहरण. 320x240 पिक्सल के साइज़ वाले बॉक्स को INTRINSIC
SIZE के लेबल के साथ दिखाया गया है. इसमें 256x192 पिक्सल का एक छोटा बॉक्स है, जो एचटीएमएल img एलिमेंट को दिखाता है. इस एलिमेंट पर सीएसएस लागू की गई है. इस बॉक्स को EXTRINSIC
SIZE लेबल किया गया है. दाईं ओर एक बॉक्स है, जिसमें एलिमेंट पर लागू की गई सीएसएस है. यह img एलिमेंट के लेआउट में बदलाव करती है, ताकि उसका एक्सट्रिंसिक साइज़, उसके इंट्रिंसिक साइज़ से अलग हो.
पहली इमेज. इंट्रिन्सिक बनाम एक्सट्रिन्सिक साइज़ का इलस्ट्रेशन. लेआउट फ़ैक्टर लागू करने के बाद, इमेज का साइज़ बदल जाता है. इस मामले में, width: 256px; और height: 192px; के CSS नियमों को लागू करने पर, 320x240 के मूल साइज़ वाली इमेज को 256x192 के बाहरी साइज़ वाली इमेज में बदल दिया जाता है.

कुछ शब्दों के बारे में जानने के बाद, अब डिवाइस के हिसाब से क्लाइंट के लिए उपलब्ध, उन संकेत की सूची पर जाएं जो आपके लिए उपलब्ध हैं.

Viewport-Width

Viewport-Width, उपयोगकर्ता के व्यूपोर्ट की चौड़ाई है. इसे सीएसएस पिक्सल में दिखाया जाता है:

Viewport-Width: 320

इस हिंट का इस्तेमाल, स्क्रीन के हिसाब से दिए गए अन्य हिंट के साथ किया जा सकता है. इससे, किसी इमेज को अलग-अलग तरह से दिखाया जा सकता है. जैसे, किसी खास स्क्रीन साइज़ (जैसे, art direction) के लिए इमेज को काटा जा सकता है. इसके अलावा, मौजूदा स्क्रीन की चौड़ाई के लिए ज़रूरी न होने वाले संसाधनों को हटाया जा सकता है.

DPR

DPR, डिवाइस पिक्सल रेशियो का छोटा नाम है. यह उपयोगकर्ता की स्क्रीन के फ़िज़िकल पिक्सल और सीएसएस पिक्सल के अनुपात की जानकारी देता है:

DPR: 2

यह हिंट, स्क्रीन की पिक्सल डेंसिटी के हिसाब से इमेज सोर्स चुनने में मददगार होता है. जैसे, srcset एट्रिब्यूट में x डिस्क्रिप्टर की तरह.

चौड़ाई

Width हिंट, sizes एट्रिब्यूट का इस्तेमाल करके <img> या <source> टैग से ट्रिगर किए गए इमेज रिसॉर्स के अनुरोधों पर दिखता है. sizes ब्राउज़र को बताता है कि संसाधन का एक्सट्रिंसिक साइज़ क्या होगा; Width उस एक्सट्रिंसिक साइज़ का इस्तेमाल करके, मौजूदा लेआउट के लिए सबसे सही साइज़ वाली इमेज का अनुरोध करता है.

उदाहरण के लिए, मान लें कि कोई उपयोगकर्ता 320 सीएसएस पिक्सल चौड़ी स्क्रीन और 2 डीपीआर वाले पेज का अनुरोध करता है. डिवाइस, <img> एलिमेंट वाले दस्तावेज़ को लोड करता है, जिसमें sizes एट्रिब्यूट की वैल्यू 85vw होती है (यानी, सभी स्क्रीन साइज़ के लिए, व्यूपोर्ट की चौड़ाई का 85% हिस्सा). अगर Width हिंट के लिए ऑप्ट-इन किया गया है, तो क्लाइंट <img> के src के अनुरोध के साथ, यह Width हिंट सर्वर को भेजेगा:

Width: 544

इस मामले में, क्लाइंट सर्वर को यह बता रहा है कि अनुरोध की गई इमेज के लिए, ऑप्टिमम इंट्रिन्सिक चौड़ाई, व्यूपोर्ट चौड़ाई (272 पिक्सल) के 85% के बराबर होगी. इसे स्क्रीन के डीपीआर (2) से गुणा करने पर, 544 पिक्सल मिलते हैं.

यह हिंट खास तौर पर अहम है, क्योंकि इसमें स्क्रीन की चौड़ाई को डेंसिटी के हिसाब से घटाया या बढ़ाया जाता है. साथ ही, इस अहम जानकारी को लेआउट में इमेज के बाहरी साइज़ के साथ भी जोड़ा जाता है. इससे, सर्वर को स्क्रीन और लेआउट, दोनों के लिए सबसे सही इमेज रिस्पॉन्स चुनने का मौका मिलता है.

Content-DPR

आपको पहले से पता है कि स्क्रीन का डिवाइस पिक्सल अनुपात होता है. हालांकि, संसाधनों का भी अपना पिक्सल अनुपात होता है. संसाधन चुनने के सबसे आसान उदाहरणों में, डिवाइसों और संसाधनों के बीच पिक्सल का अनुपात एक जैसा हो सकता है. लेकिन! जिन मामलों में DPR और Width, दोनों हेडर इस्तेमाल किए जा रहे हैं उनमें किसी संसाधन का एक्सट्रिंसिक साइज़, ऐसे मामलों में अलग-अलग हो सकता है. ऐसे में, Content-DPR के लिए दिए गए संकेत का इस्तेमाल करें.

अन्य क्लाइंट हिंट के विपरीत, Content-DPR एक अनुरोध हेडर नहीं है, जिसका इस्तेमाल सर्वर करते हैं. इसके बजाय, यह एक रिस्पॉन्स हेडर है, जिसे सर्वर को किसी रिसॉर्स को चुनने के लिए DPR और Width हिंट का इस्तेमाल करने पर भेजना ज़रूरी है. Content-DPR की वैल्यू, इस समीकरण का नतीजा होनी चाहिए:

Content-DPR = [चुनी गई इमेज के संसाधन का साइज़] / ([Width] / [DPR])

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

Device-Memory

Device-Memory, डिवाइस मेमोरी एपीआई का हिस्सा है. इससे पता चलता है कि मौजूदा डिवाइस में लगभग कितनी मेमोरी है. इसे गीगाबाइट (जीबी) में दिखाया जाता है:

Device-Memory: 2

इस हिंट का इस्तेमाल, सीमित मेमोरी वाले डिवाइसों पर ब्राउज़र को भेजे जाने वाले JavaScript की संख्या को कम करने के लिए किया जा सकता है. ऐसा इसलिए, क्योंकि आम तौर पर ब्राउज़र, सबसे ज़्यादा संसाधनों का इस्तेमाल करने वाले कॉन्टेंट टाइप के तौर पर JavaScript को लोड करते हैं. इसके अलावा, कम डीपीआर वाली इमेज भी भेजी जा सकती हैं, क्योंकि उन्हें डिकोड करने के लिए कम मेमोरी का इस्तेमाल होता है.

नेटवर्क से जुड़े सुझाव

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

आरटीटी

RTT हिंट, ऐप्लिकेशन लेयर पर मिलीसेकंड में अनुमानित राउंड ट्रिप टाइम दिखाता है. ट्रांसपोर्ट लेयर आरटीटी के उलट, RTT हिंट में, सर्वर प्रोसेसिंग का समय शामिल होता है.

RTT: 125

यह हिंट इसलिए काम का है, क्योंकि लोडिंग की परफ़ॉर्मेंस में इंतज़ार का समय अहम भूमिका निभाता है. RTT हिंट का इस्तेमाल करके, हम नेटवर्क की परफ़ॉर्मेंस के आधार पर फ़ैसले ले सकते हैं.इससे, पूरे अनुभव को तेज़ी से डिलीवर करने में मदद मिलती है. उदाहरण के लिए, कुछ अनुरोधों को छोड़कर.

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

Downlink: 2.5

RTT के साथ Downlink का इस्तेमाल करके, नेटवर्क कनेक्शन की क्वालिटी के आधार पर, उपयोगकर्ताओं को कॉन्टेंट डिलीवर करने के तरीके में बदलाव किया जा सकता है.

ECT

ECT हिंट का मतलब है इफ़ेक्टिव कनेक्शन टाइप. इसकी वैल्यू, कनेक्शन टाइप की सूची में से एक होती है. इसमें से हर टाइप, RTT और Downlink वैल्यू की तय की गई रेंज में मौजूद कनेक्शन के बारे में बताता है.

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

ECT: 2g

ECT के लिए मान्य वैल्यू 4g, 3g, 2g, और slow-2g हैं. इस संकेत का इस्तेमाल, कनेक्शन की क्वालिटी का आकलन करने के लिए शुरुआती बिंदु के तौर पर किया जा सकता है. इसके बाद, RTT और Downlink के संकेत का इस्तेमाल करके, इस आकलन को बेहतर बनाया जा सकता है.

Save-Data

Save-Data, नेटवर्क की स्थिति के बारे में बताने वाला संकेत नहीं है, बल्कि यह उपयोगकर्ता की प्राथमिकता है. इससे पता चलता है कि पेजों को कम डेटा भेजना चाहिए.

मेरा सुझाव है कि Save-Data को नेटवर्क के सुझाव के तौर पर वर्गीकृत करें, क्योंकि इसके साथ की जाने वाली कई कार्रवाइयां, नेटवर्क के अन्य सुझावों से मिलती-जुलती हैं. उपयोगकर्ता, ज़्यादा इंतज़ार/कम बैंडविड्थ वाले वातावरण में भी इसे चालू कर सकते हैं. यह हिंट, मौजूद होने पर हमेशा इस तरह दिखता है:

Save-Data: on

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

सभी चीज़ों को एक साथ जोड़ना

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

रिस्पॉन्सिव इमेज

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

<picture> और srcset शानदार टूल हैं. हालांकि, इनका इस्तेमाल करने के मुश्किल उदाहरणों के लिए, इन्हें बनाने और मैनेज करने में काफ़ी समय लग सकता है. हम मार्कअप जनरेशन को ऑटोमेट कर सकते हैं. हालांकि, ऐसा करना मुश्किल है, क्योंकि <picture> और srcset की सुविधाएं इतनी जटिल हैं कि उन्हें ऑटोमेट करने के लिए, उन्हें इस तरह से ऑटोमेट करना होगा कि वे अपनी सुविधाएं बरकरार रख सकें.

क्लाइंट के संकेत, इसे आसान बना सकते हैं. क्लाइंट के सुझावों के आधार पर इमेज के जवाबों पर बातचीत करने का तरीका कुछ ऐसा हो सकता है:

  1. अगर आपके वर्कफ़्लो में यह सुविधा काम करती है, तो सबसे पहले Viewport-Width के सुझाव पर क्लिक करके, इमेज ट्रीटमेंट (जैसे, आर्ट डायरेक्टेड इमेजरी) चुनें.
  2. Width और DPR के सुझावों को देखकर, इमेज का रिज़ॉल्यूशन चुनें. साथ ही, इमेज के लेआउट साइज़ और स्क्रीन डेंसिटी के हिसाब से कोई सोर्स चुनें. यह वैसे ही है जैसे srcset में x और w डिस्क्रिप्टर काम करते हैं.
  3. ब्राउज़र के साथ काम करने वाला सबसे अच्छा फ़ाइल फ़ॉर्मैट चुनें. Accept इससे हमें ज़्यादातर ब्राउज़र में काम करने में मदद मिलती है.

लकड़ी की नकली कंपनी के क्लाइंट के लिए, मैंने PHP में एक ऐसा रूटीन बनाया है जो क्लाइंट के सुझावों का इस्तेमाल करके, रिस्पॉन्सिव इमेज चुनता है. इसका मतलब है कि सभी उपयोगकर्ताओं को यह मार्कअप भेजने के बजाय:

<picture>
  <source
    srcset="
      company-photo-256w.webp   256w,
      company-photo-512w.webp   512w,
      company-photo-768w.webp   768w,
      company-photo-1024w.webp 1024w,
      company-photo-1280w.webp 1280w
    "
    type="image/webp"
  />
  <img
    srcset="
      company-photo-256w.jpg   256w,
      company-photo-512w.jpg   512w,
      company-photo-768w.jpg   768w,
      company-photo-1024w.jpg 1024w,
      company-photo-1280w.jpg 1280w
    "
    src="company-photo-256w.jpg"
    sizes="(min-width: 560px) 251px, 88.43vw"
    alt="The Sconnie Timber Staff!"
  />
</picture>

अलग-अलग ब्राउज़र के साथ काम करने की सुविधा के आधार पर, हमने इसे इन तक कम कर दिया है:

<img
  src="/image/sizes:true/company-photo.jpg"
  sizes="(min-width: 560px) 251px, 88.43vw"
  alt="SAY CHEESY PICKLES."
/>

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

मुझे लगता है कि आपका पहला सवाल यह है कि “क्या यह सिर्फ़ बैक-एंड पर <picture> और srcset को फिर से लागू करना है?”

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

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

हालांकि, आपको इमेज चुनने का लॉजिक खुद लिखने की ज़रूरत नहीं है. w_auto पैरामीटर का इस्तेमाल करने पर, Cloudinary इमेज के जवाब तैयार करने के लिए क्लाइंट हिंट का इस्तेमाल करता है. इससे पता चला है कि क्लाइंट हिंट के साथ काम करने वाले ब्राउज़र का इस्तेमाल करने पर, औसत उपयोगकर्ताओं ने 42% कम बाइट डाउनलोड किए.

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

धीमे नेटवर्क पर उपयोगकर्ताओं की मदद करना

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

Sconnie Timber की साइट के लिए, हम नेटवर्क के धीमे होने पर लोड को कम करने के लिए कदम उठाते हैं. इसके लिए, हमारे बैक-एंड कोड में Save-Data, ECT, RTT, और Downlink हेडर की जांच की जाती है. ऐसा करने के बाद, हम नेटवर्क क्वालिटी का स्कोर जनरेट करते हैं. इसका इस्तेमाल करके, यह तय किया जा सकता है कि उपयोगकर्ताओं को बेहतर अनुभव देने के लिए, हमें क्या करना चाहिए. यह नेटवर्क स्कोर, 0 और 1 के बीच होता है. 0 का मतलब है कि नेटवर्क की क्वालिटी सबसे खराब है और 1 का मतलब है कि नेटवर्क की क्वालिटी सबसे अच्छी है.

सबसे पहले, हम यह जांच करते हैं कि Save-Data मौजूद है या नहीं. अगर ऐसा है, तो स्कोर 0 पर सेट किया जाता है. ऐसा इसलिए, क्योंकि हम मानते हैं कि उपयोगकर्ता चाहता है कि हम ऐप्लिकेशन को हल्का और तेज़ बनाने के लिए ज़रूरी कदम उठाएं.

अगर Save-Data मौजूद नहीं है, तो हम ECT, RTT, और Downlink के सुझावों की वैल्यू का इस्तेमाल करके, नेटवर्क कनेक्शन की क्वालिटी बताने वाले स्कोर का हिसाब लगाते हैं. नेटवर्क स्कोर जनरेट करने वाला सोर्स कोड, GitHub पर उपलब्ध है. इसका मतलब है कि अगर हम नेटवर्क से जुड़े सुझावों का इस्तेमाल किसी तरीके से करते हैं, तो हम उन लोगों के लिए अनुभव को बेहतर बना सकते हैं जो धीमे नेटवर्क का इस्तेमाल कर रहे हैं.

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

जब साइटें, क्लाइंट के दिए गए हिंट के हिसाब से बदल जाती हैं, तो हमें “पूरी तरह से या कुछ भी नहीं” वाला तरीका अपनाने की ज़रूरत नहीं होती. हम यह तय कर सकते हैं कि कौनसे संसाधन भेजने हैं. हम रिस्पॉन्सिव इमेज चुनने के लॉजिक में बदलाव कर सकते हैं, ताकि किसी डिसप्ले के लिए खराब क्वालिटी की इमेज भेजी जा सकें. इससे नेटवर्क क्वालिटी खराब होने पर, लोड होने की परफ़ॉर्मेंस को तेज़ किया जा सकता है.

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

Sconnie Timber साइट का WebPagetest वॉटरफ़ॉल, जो धीमे नेटवर्क कनेक्शन पर सभी संसाधनों को लोड कर रहा है.
तीसरी इमेज. धीमे कनेक्शन पर इमेज, स्क्रिप्ट, और फ़ॉन्ट लोड करने वाली ज़्यादा संसाधनों वाली साइट.

अब उसी साइट के लिए, उसी धीमे कनेक्शन पर वॉटरफ़ॉल का डेटा. हालांकि, इस बार साइट, पेज के ऐसे रिसॉर्स को हटाने के लिए क्लाइंट हिंट का इस्तेमाल करती है जो ज़रूरी नहीं हैं:

Sconnie Timber साइट का WebPagetest वॉटरफ़ॉल, जिसमें क्लाइंट के सुझावों का इस्तेमाल करके यह तय किया गया है कि धीमे नेटवर्क कनेक्शन पर ग़ैर-ज़रूरी संसाधनों को लोड न किया जाए.
चौथी इमेज. एक ही कनेक्शन पर एक ही साइट, ज़्यादा तेज़ी से लोड करने के लिए सिर्फ़ “अगर हो सके, तो इस्तेमाल करें” रिसॉर्स को बाहर रखा गया है.

क्लाइंट हिंट की मदद से, पेज लोड होने में लगने वाला समय 45 सेकंड से घटकर उस समय के दसवें हिस्से से भी कम हो गया. इस स्थिति में, क्लाइंट हिंट के फ़ायदों को ज़्यादा से ज़्यादा ज़ोर नहीं दिया जा सकता. यह धीमे नेटवर्क पर ज़रूरी जानकारी पाने वाले उपयोगकर्ताओं के लिए काफ़ी फ़ायदेमंद हो सकता है.

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

// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";

यहां "4g", सबसे अच्छी क्वालिटी के नेटवर्क कनेक्शन को दिखाता है, जिसकी जानकारी ECT हेडर में दी गई है. अगर हम $ect को "4g" पर शुरू करते हैं, तो क्लाइंट के संकेत के साथ काम न करने वाले ब्राउज़र पर कोई असर नहीं पड़ेगा. ऑप्ट-इन करें!

कैश मेमोरी का ध्यान रखें!

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

Vary: DPR, Width

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

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

सेवा वर्कर में क्लाइंट हिंट

कॉन्टेंट नेगोशिएशन की सुविधा अब सिर्फ़ सर्वर के लिए नहीं है! सेवा वर्कर, क्लाइंट और सर्वर के बीच प्रॉक्सी के तौर पर काम करते हैं. इसलिए, आपके पास यह कंट्रोल करने का विकल्प होता है कि JavaScript के ज़रिए संसाधन कैसे डिलीवर किए जाएं. इसमें क्लाइंट हिंट भी शामिल हैं. सेवा वर्कर के fetch इवेंट में, किसी संसाधन के अनुरोध हेडर को पढ़ने के लिए, event ऑब्जेक्ट के request.headers.get तरीके का इस्तेमाल किया जा सकता है. इसके लिए, यह तरीका अपनाएं:

self.addEventListener('fetch', (event) => {
  let dpr = event.request.headers.get('DPR');
  let viewportWidth = event.request.headers.get('Viewport-Width');
  let width = event.request.headers.get('Width');

  event.respondWith(
    (async function () {
      // Do what you will with these hints!
    })(),
  );
});

आपने जिस क्लाइंट हिंट हेडर के लिए ऑप्ट इन किया है उसे इस तरह पढ़ा जा सकता है. हालांकि, इस जानकारी को पाने का यह एकमात्र तरीका नहीं है. नेटवर्क के हिसाब से सलाह, navigator ऑब्जेक्ट में मौजूद इन मिलती-जुलती JavaScript प्रॉपर्टी में पढ़ी जा सकती हैं:

क्लाइंट हिंट JS में मिलता-जुलता
`ECT` `navigator.connection.effectiveType`
`RTT` `navigator.connection.rtt`
`Save-Data` `navigator.connection.saveData`
`डाउनलिंक` `navigator.connection.downlink`
`Device-Memory` `navigator.deviceMemory`
फ़ाइल टाइप के लिए Imagemin प्लगिन.

ये एपीआई हर जगह उपलब्ध नहीं हैं. इसलिए, आपको in ऑपरेटर की मदद से, सुविधा की जांच करनी होगी:

if ('connection' in navigator) {
  // Work with netinfo API properties in JavaScript!
}

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

आखिर में खास जानकारी

क्लाइंट हिंट की मदद से, हम उपयोगकर्ताओं के लिए अनुभव को तेज़ बना सकते हैं. हम उपयोगकर्ता के डिवाइस की सुविधाओं के आधार पर मीडिया दिखा सकते हैं. इससे, <picture> और srcset पर निर्भर रहने के बजाय, रिस्पॉन्सिव इमेज दिखाना आसान हो जाता है. खास तौर पर, इस्तेमाल के मुश्किल मामलों में. इससे हमें डेवलपमेंट के लिए, न सिर्फ़ कम समय और मेहनत लगती है, बल्कि संसाधनों को ऑप्टिमाइज़ करने में भी मदद मिलती है. खास तौर पर, इमेज को इस तरह ऑप्टिमाइज़ किया जा सकता है कि वह और srcset की तुलना में, उपयोगकर्ता की स्क्रीन को ज़्यादा बेहतर तरीके से टारगेट कर सके.

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

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

संसाधन

इस लेख में अहम सुझाव देने और उसमें बदलाव करने के लिए, इल्या ग्रिगोरिक, एरिक पोर्टिस, जेफ़ पॉस्निक, योआव वाइस, और एस्टेल वाइल का धन्यवाद.