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

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

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

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

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

कॉन्टेंट पर बातचीत करने के तरीकों के एक उदाहरण में 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 में कोई इमेज खोली है, तो इमेज के साइज़ वाले डायलॉग में दिखाए गए डाइमेंशन से, इमेज के असल साइज़ के बारे में पता चलता है.

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

<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; के सीएसएस नियमों को लागू करने पर, 320x240 साइज़ की इमेज को बाहर की इमेज 256x192 में बदल दिया जाता है.

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

Viewport-Width

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

Viewport-Width: 320

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

डीपीआर

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

DPR: 2

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

चौड़ाई

Width संकेत, इमेज से जुड़े ऐसे रिसॉर्स के अनुरोधों पर दिखता है जिन्हें <img> या sizes एट्रिब्यूट का इस्तेमाल करके <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 को दिखाता है कि मेमोरी मौजूदा डिवाइस में मौजूद GitHub की अनुमानित मात्रा:

Device-Memory: 2

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

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

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

आरटीटी

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

संसाधन

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