इस मॉड्यूल में, आप जानेंगे कि ब्राउज़र को इमेज का विकल्प कैसे दिया जाए, ताकि वह इस बारे में सबसे अच्छा फ़ैसला कर सके कि क्या दिखाना है. srcset
किसी खास ब्रेकपॉइंट पर इमेज सोर्स को बदलने का तरीका नहीं है. साथ ही, इसका इस्तेमाल एक इमेज को दूसरी इमेज से बदलने के लिए नहीं किया जाना चाहिए. ये सिंटैक्स, ब्राउज़र को एक बहुत मुश्किल समस्या को हल करने में मदद करते हैं. यह समस्या हम पर निर्भर नहीं करती: उपयोगकर्ता के ब्राउज़िंग कॉन्टेक्स्ट के हिसाब से इमेज के सोर्स के लिए बिना किसी रुकावट के अनुरोध करना और उसे रेंडर करना. इसमें व्यूपोर्ट का साइज़, डिसप्ले डेंसिटी, उपयोगकर्ता की प्राथमिकताएं, बैंडविथ, और अन्य कई चीज़ें शामिल हैं.
यह एक बहुत बड़ा सवाल है—जब हम सिर्फ़ वेब के लिए कोई इमेज मार्कअप करते हैं, तब हम इस पर ध्यान नहीं देना चाहते. इसे अच्छी तरह से करने के लिए, हमारे पास ज़्यादा जानकारी नहीं होती.
x
की मदद से सघनता का ब्यौरा देना
किसी भी चौड़ाई वाला <img>
, किसी भी ब्राउज़िंग कॉन्टेक्स्ट में व्यूपोर्ट के बराबर जगह लेगा. भले ही, उपयोगकर्ता के डिसप्ले की डेंसिटी कुछ भी हो—अपनी स्क्रीन बनाने वाले फ़िज़िकल पिक्सल की संख्या. उदाहरण के लिए, 400px
की चौड़ाई वाली इमेज, ओरिजनल Google Pixel
और नए Pixel 6 Pro, दोनों के ब्राउज़र के पूरे व्यूपोर्ट को इस्तेमाल कर लेगी. दोनों डिवाइसों में सामान्य रूप से 412px
लॉजिकल पिक्सल का व्यूपोर्ट है.
Pixel 6 Pro का डिसप्ले ज़्यादा तेज़ है. हालांकि: 6 Pro का फ़िज़िकल रिज़ॉल्यूशन 1440 × 3120 पिक्सल है, जबकि Pixel 1080 × 1920 पिक्सल है—यानी यह स्क्रीन को बनाने वाले हार्डवेयर पिक्सल की संख्या है.
डिवाइस के लॉजिकल पिक्सल और फ़िज़िकल पिक्सल के बीच का अनुपात, उस डिसप्ले (डीपीआर) के लिए डिवाइस पिक्सल का अनुपात होता है. डीपीआर का हिसाब, डिवाइस के असल स्क्रीन रिज़ॉल्यूशन को व्यूपोर्ट के सीएसएस पिक्सल से भाग देकर लगाया जाता है.
इसलिए, ओरिजनल Pixel का डीपीआर 2.6 और Pixel 6 Pro का डीपीआर 3.5 है.
iPhone 4, जो कि 1 से ज़्यादा डीपीआर वाला पहला डिवाइस है, डिवाइस पिक्सल रेशियो 2 की रिपोर्ट करता है—स्क्रीन का फ़िज़िकल रिज़ॉल्यूशन उसके हिसाब से दोगुना रिज़ॉल्यूशन होता है. iPhone 4 से पहले के किसी भी डिवाइस का DPR 1: एक लॉजिकल पिक्सल से एक फ़िज़िकल पिक्सल था.
अगर आपको 2
के DPR वाले डिसप्ले पर वह 400px
चौड़ी इमेज दिखती है, तो हर लॉजिकल पिक्सल, डिसप्ले के फ़िज़िकल पिक्सल में से
चार पिक्सल में रेंडर होता है: दो हॉरिज़ॉन्टल और दो वर्टिकल. इमेज को ज़्यादा सघनता वाले डिसप्ले का फ़ायदा नहीं मिलता. यह इमेज वैसी ही दिखेगी जैसी
यह 1
के डीपीआर वाले डिसप्ले पर दिखती है. बेशक, ब्राउज़र के रेंडरिंग इंजन से "ड्रॉ किया गया" कुछ भी—उदाहरण के लिए, टेक्स्ट, सीएसएस के आकार या SVG की मदद से, उसे ज़्यादा डेंसिटी वाले डिसप्ले के हिसाब से तैयार किया जाएगा. हालांकि, जब आपने इमेज फ़ॉर्मैट और कंप्रेशन से सीखा, तब रास्टर इमेज पर पिक्सल के ग्रिड तय हो जाते हैं. ऐसा हो सकता है कि यह हमेशा साफ़ तौर पर साफ़ न दिखे, लेकिन ज़्यादा डेंसिटी वाले डिसप्ले के हिसाब से चुनी गई रास्टर इमेज, आस-पास के पेज की तुलना में कम रिज़ॉल्यूशन वाली दिखेगी.
इसे बढ़ाने से रोकने के लिए, रेंडर की जा रही इमेज की चौड़ाई कम से कम 800
पिक्सल होनी चाहिए. इसे छोटा करके 400 लॉजिकल पिक्सल चौड़ी जगह में फ़िट करने के लिए, 800 पिक्सल वाले इमेज सोर्स की पिक्सल डेंसिटी दोगुनी हो जाती है. यह 2
के डीपीआर वाले डिसप्ले पर दिखता है. इससे वह अच्छा और साफ़ दिखेगा.
1
के डीपीआर वाले डिसप्ले में किसी इमेज की बढ़ी हुई सघनता का इस्तेमाल नहीं किया जा सकता. इसलिए, डिसप्ले से मेल खाने के लिए इसे कम करके
किया जाएगा और जैसा कि आपको पता है, डाउनस्केल किया गया इमेज बिलकुल ठीक दिखेगी. कम सघनता वाले डिसप्ले पर, ज़्यादा सघनता वाले डिसप्ले के लिए सही इमेज,
कम डेंसिटी वाली किसी दूसरी इमेज की तरह दिखेगी.
जैसा कि आपने इमेज और परफ़ॉर्मेंस सेक्शन में जाना है कि अगर कोई उपयोगकर्ता, कम डेंसिटी वाले डिसप्ले पर मौजूद किसी इमेज के सोर्स को 400px
तक छोटा करके देखता है, तो उसे सिर्फ़ 400px
की चौड़ाई वाले सोर्स की ज़रूरत होगी. हालांकि, साइज़ की बड़ी इमेज सभी लोगों के लिए काम करेगी, लेकिन
कम सघनता वाले डिसप्ले पर रेंडर किया गया बहुत बड़ा, ज़्यादा रिज़ॉल्यूशन वाला इमेज सोर्स, किसी भी दूसरी छोटी, कम सघनता वाली इमेज की तरह दिखेगा, लेकिन बहुत धीमा लगेगा.
जैसा कि आपका अनुमान होगा, 1 के डीपीआर वाले मोबाइल डिवाइस बेहद कम ही होते हैं. हालांकि, "डेस्कटॉप" पर ब्राउज़ करने के कॉन्टेक्स्ट में ऐसा होना अब भी आम बात है. Matt Hobbs की ओर से शेयर किए गए डेटा के मुताबिक, नवंबर 2022 में GOV.UK ब्राउज़िंग सेशन में से करीब 18% लोगों ने 1. हालांकि, ज़्यादा डेंसिटी वाली इमेज उन उपयोगकर्ताओं की उम्मीद के मुताबिक दिखेगी, जिन पर वे बहुत ज़्यादा बैंडविड्थ और प्रोसेसिंग लागत का इस्तेमाल कर सकते हैं. यह खास बात यह है कि पुराने और कम क्षमता वाले डिवाइसों का इस्तेमाल करने वाले उपयोगकर्ताओं को, अब भी कम डेंसिटी वाले डिसप्ले की संभावना है.
srcset
का इस्तेमाल करने से यह पक्का होता है कि सिर्फ़ हाई रिज़ॉल्यूशन डिसप्ले वाले डिवाइसों को साफ़ दिखने के लिए, बड़े साइज़ के इमेज सोर्स मिलें. इसके लिए, कम रिज़ॉल्यूशन वाले डिसप्ले वाले उपयोगकर्ताओं को बैंडविड्थ की उतनी ही लागत आती है.
srcset
एट्रिब्यूट किसी इमेज को रेंडर करने के लिए, एक या उससे ज़्यादा कॉमा लगाकर अलग किए गए उम्मीदवारों की पहचान करता है. हर कैंडिडेट में दो चीज़ें होती हैं: जैसा कि src
में इस्तेमाल किया जाएगा और एक सिंटैक्स, जो इमेज के सोर्स के बारे में बताता है. srcset
के हर कैंडिडेट की जानकारी, उसकी चौड़ाई ("w
सिंटैक्स") या तय डेंसिटी ("x
सिंटैक्स") के हिसाब से दी जाती है.
x
सिंटैक्स "यह सोर्स इस डेंसिटी वाले डिसप्ले के लिए सही है" का शॉर्टहैंड है. इसका मतलब है कि 2x
के बाद वाला कैंडिडेट, 2 के डीपीआर वाले डिसप्ले के लिए सही होता है.
<img src="low-density.jpg" srcset="double-density.jpg 2x" alt="...">
srcset
के साथ काम करने वाले ब्राउज़र में दो सुझाव दिखाए जाएंगे: double-density.jpg
, जो 2x
दो DPR वाले डिस्प्ले के लिए सही बताया जाएगा और src
एट्रिब्यूट में low-density.jpg
दिखेगा. अगर srcset
में कुछ ज़्यादा सही नहीं मिलता है, तो चुना गया उम्मीदवार. जिन ब्राउज़र में srcset
का इस्तेमाल नहीं किया जा सकता उनमें एट्रिब्यूट और उसके कॉन्टेंट को नज़रअंदाज़ किया जाएगा. src
के कॉन्टेंट का अनुरोध सामान्य तरीके से किया जाएगा.
निर्देशों के लिए, srcset
एट्रिब्यूट में दी गई वैल्यू को समझना आसान है. वह 2x
, ब्राउज़र को यह बताता है कि उससे जुड़ी सोर्स फ़ाइल, 2 के डीपीआर वाले डिसप्ले पर इस्तेमाल करने के लिए सही होगी. साथ ही, सोर्स के बारे में जानकारी मिलती है. यह ब्राउज़र को यह नहीं बताता कि उस सोर्स को कैसे इस्तेमाल करना है, सिर्फ़ यह ब्राउज़र को बताता है कि सोर्स को कैसे इस्तेमाल किया जा सकता है. यह मामूली लेकिन अहम फ़र्क़ है: यह एक डबल डेंसिटी वाली इमेज है, न कि डबल सघनता वाले डिसप्ले पर इस्तेमाल करने के लिए इमेज नहीं.
"यह सोर्स 2x
डिसप्ले के लिए सही है" और "इस सोर्स को 2x
डिसप्ले पर इस्तेमाल करें" वाले सिंटैक्स के बीच का अंतर थोड़ा-बहुत है. हालांकि, डिसप्ले डेंसिटी, आपस में लिंक किए गए कई फ़ैक्टर की बड़ी संख्या में से एक है. इसका इस्तेमाल ब्राउज़र, इमेज बनाने के उम्मीदवार के बारे में तय करने के लिए करता है. इनमें से सिर्फ़ कुछ के बारे में आपको पता है. उदाहरण के लिए: व्यक्तिगत रूप से, आपके लिए यह तय करना मुमकिन है कि किसी उपयोगकर्ता ने prefers-reduced-data
मीडिया क्वेरी के ज़रिए बैंडविथ सेव करने वाले ब्राउज़र की प्राथमिकता को चालू किया है. इसका इस्तेमाल, उपयोगकर्ताओं को हमेशा कम डेंसिटी वाली इमेज में ऑप्ट इन करने के लिए करें, भले ही उनकी डिसप्ले डेंसिटी कुछ भी हो. हालांकि, जब तक हर डेवलपर की ओर से हर वेबसाइट पर इसे एक ही तरीके से लागू नहीं किया जाता, तब तक उपयोगकर्ता के लिए यह ज़्यादा काम का नहीं होगा.
ऐसा हो सकता है कि किसी एक साइट पर उनकी पसंद का सम्मान किया गया हो और अगली साइट पर इमेज की बैंडविड्थ कम करने वाली दीवार का इस्तेमाल किया जाए.
srcset
/sizes
में रिसॉर्स चुनने के लिए इस्तेमाल होने वाले एल्गोरिदम को समझना मुश्किल होता है. इससे ब्राउज़र कम डेंसिटी वाली इमेज को, बैंडविथ कम करने वाली या डेटा खर्च को कम करने की प्राथमिकता पर निर्भर कर सकते हैं. ऐसा करते समय, हम इसकी ज़िम्मेदारी नहीं लेते कि हम कैसे, कब या किस थ्रेशोल्ड पर हैं. ऐसी ज़िम्मेदारियों को लेने और अतिरिक्त काम करने में कोई अर्थ नहीं है—जिसे ब्राउज़र आपके लिए संभालने के लिए बेहतर ढंग से तैयार है.
w
से चौड़ाई का ब्यौरा दिया जा रहा है
srcset
, इमेज सोर्स के उम्मीदवारों के लिए दूसरे टाइप के डिस्क्रिप्टर को स्वीकार करता है. यह उससे कहीं ज़्यादा दमदार है—और हमारे मक़सद से, समझने में बहुत आसान है. किसी उम्मीदवार को दिए गए डिसप्ले सघनता के लिए सही डाइमेंशन के तौर पर फ़्लैग करने के बजाय, w
सिंटैक्स हर कैंडिडेट सोर्स की चौड़ाई के बारे में बताता है. फिर से, हर कैंडिडेट के अपने डाइमेंशन के लिए
एक जैसी सेव की गई है. एक जैसा कॉन्टेंट, काट-छांट करना, और आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) एक जैसा. हालांकि, इस मामले में आपको उपयोगकर्ता का ब्राउज़र दो कैंडिडेट में से चुनना होगा:
small.jpg, 600 पिक्सल की चौड़ाई वाला सोर्स औरlarge.jpg, 1200 पिक्सल की चौड़ाई वाला सोर्स.
srcset="small.jpg 600w, large.jpg 1200w"
यह ब्राउज़र को यह नहीं बताता है कि इस जानकारी के साथ क्या करना है—सिर्फ़ इमेज दिखाने के लिए उम्मीदवारों की सूची के साथ इसे मुहैया कराता है.
ब्राउज़र किस सोर्स को रेंडर करना है, यह तय करने से पहले, आपको इसे थोड़ी और जानकारी देनी होगी: पेज पर इमेज को रेंडर करने के तरीके का ब्यौरा. ऐसा करने के लिए, sizes
एट्रिब्यूट का इस्तेमाल करें.
sizes
के साथ इस्तेमाल के बारे में जानकारी दी जा रही है
जब इमेज ट्रांसफ़र करने की बात आती है, तो ब्राउज़र की परफ़ॉर्मेंस बेहतरीन होती है. इमेज एसेट के लिए अनुरोध, स्टाइलशीट या JavaScript के अनुरोध से पहले ही शुरू किए जाते हैं. कई बार, मार्कअप के पूरी तरह पार्स होने से भी पहले ही अनुरोध किए जाते हैं. जब ब्राउज़र ऐसे अनुरोध करता है, तो उसके पास मार्कअप के अलावा, पेज के बारे में कोई जानकारी नहीं होती. ऐसा हो सकता है कि उसने अभी तक बाहरी स्टाइलशीट के लिए अनुरोध न भी किए हों, उन्हें लागू करने की अनुमति न दें. जब ब्राउज़र आपके मार्कअप को पार्स करता है और बाहरी अनुरोध करना शुरू करता है, तब उसमें सिर्फ़ ब्राउज़र के लेवल की जानकारी मौजूद होती है. जैसे, उपयोगकर्ता के व्यूपोर्ट का साइज़, उपयोगकर्ता के डिसप्ले का पिक्सल सघनता, उपयोगकर्ता की प्राथमिकताएं वगैरह.
यह हमें इस बारे में कुछ भी नहीं बताता कि पेज लेआउट में इमेज को किस तरह रेंडर किया जाएगा. यह img
के साइज़ की ऊपरी सीमा के लिए प्रॉक्सी के तौर पर व्यूपोर्ट का इस्तेमाल भी नहीं कर सकता, क्योंकि यह ऊपर से नीचे की ओर स्क्रोल होने वाले कंटेनर को ले सकता है. इसलिए, हमें ब्राउज़र को यह जानकारी देनी होगी और इसे मार्कअप का इस्तेमाल करके सबमिट करना होगा. इन अनुरोधों के लिए, हम बस इतना ही इस्तेमाल कर पाएंगे.
srcset
की तरह, sizes
का मकसद भी मार्कअप को पार्स करते ही इमेज के बारे में जानकारी उपलब्ध कराना है. जिस तरह srcset
एट्रिब्यूट, "सोर्स फ़ाइलें और उनसे जुड़े साइज़ यहां दिए गए हैं" की शॉर्टहैंड की तरह है, उसी तरह sizes
एट्रिब्यूट की मदद से, "यहां लेआउट में रेंडर की गई इमेज का साइज़ दिया गया है. इमेज के बारे में जानकारी देने का तरीका, व्यूपोर्ट के हिसाब से होता है—हालांकि, इमेज के लिए अनुरोध करने पर, ब्राउज़र के पास सिर्फ़ व्यूपोर्ट साइज़ की जानकारी होती है.
यह प्रिंट में थोड़ा जटिल लग सकता है, लेकिन इसे समझना बहुत आसान है:
<img
sizes="80vw"
srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
src="fallback.jpg"
alt="...">
यहां, sizes
की यह वैल्यू ब्राउज़र को बताती है कि हमारे लेआउट में जो स्पेस img
में है उसकी चौड़ाई 80vw
—80% व्यूपोर्ट की है. याद रखें कि यह कोई निर्देश नहीं है, बल्कि पेज के लेआउट में इमेज के साइज़ की जानकारी है. इसमें यह नहीं लिखा है कि "इस इमेज को
व्यूपोर्ट के 80% हिस्से में शामिल कर लें", लेकिन "पेज के रेंडर हो जाने के बाद यह इमेज, व्यूपोर्ट के 80% हिस्से में चली जाएगी."
डेवलपर के तौर पर, आपका काम पूरा हो जाएगा. आपने srcset
में कैंडिडेट सोर्स की सूची और sizes
में अपनी इमेज की चौड़ाई के बारे में सही जानकारी दी है. srcset
में x
सिंटैक्स की तरह ही, बाकी जानकारी ब्राउज़र पर निर्भर करती है.
हालांकि, इस जानकारी का इस्तेमाल कैसे किया जाता है, इसे पूरी तरह से समझने के लिए, आइए उन फ़ैसलों के बारे में बात करते हैं जो किसी उपयोगकर्ता के ब्राउज़र को यह मार्कअप मिलने पर करते हैं:
आपने ब्राउज़र को सूचना दी है कि यह इमेज, उपलब्ध व्यूपोर्ट का 80% हिस्सा लेगी. इसलिए, अगर हम 1000 पिक्सल चौड़े व्यूपोर्ट वाले डिवाइस पर इस img
को रेंडर करते हैं, तो यह इमेज 800 पिक्सल का इस्तेमाल कर लेगी. इसके बाद, ब्राउज़र उस वैल्यू को लेता है और उसे srcset
में बताए गए इमेज सोर्स के हर कैंडिडेट की चौड़ाई से भाग देता है. सबसे छोटे सोर्स का साइज़ 600 पिक्सल होता है,
इसलिए: 600÷800=.75. हमारी मीडियम इमेज 1200 पिक्सल चौड़ी है: 1200÷800=1.5. हमारी सबसे बड़ी इमेज 2000 पिक्सल चौड़ी है: 2000÷800=2.5.
इन कैलकुलेशन के नतीजों (.75
, 1.5
, और 2.5
) के आधार पर, खास तौर पर उपयोगकर्ता के व्यूपोर्ट के साइज़ के हिसाब से डीपीआर विकल्प तैयार किए जाते हैं. ब्राउज़र के पास उपयोगकर्ता की डिसप्ले डेंसिटी की जानकारी भी होती है. इसलिए, यह कई तरह के फ़ैसले लेता है:
व्यूपोर्ट के इस साइज़ में, small.jpg
कैंडिडेट को खारिज कर दिया जाता है, फिर चाहे उपयोगकर्ता की डिसप्ले डेंसिटी कुछ भी हो—यानी डीपीआर 1
से कम होता है. इस सोर्स को किसी भी उपयोगकर्ता के लिए बड़ा करना होगा. इसलिए, यह सही नहीं है. 1
डीपीआर वाले डिवाइस पर medium.jpg
सबसे मिलती-जुलती जानकारी देता है—वह सोर्स 1.5
के डीपीआर में दिखाने के लिए सही होता है. इसलिए, यह ज़रूरत से थोड़ा बड़ा होता है, लेकिन याद रखें कि डाउनस्केल करना, विज़ुअल तौर पर आसान प्रोसेस है. 2 के डीपीआर वाले डिवाइस पर,large.jpg
सबसे ज़्यादा मिलता-जुलता है, इसलिए इसे चुना जाता है.
अगर उसी इमेज को 600 पिक्सल चौड़ी व्यूपोर्ट पर रेंडर किया जाता है, तो इन सभी गणित का नतीजा पूरी तरह से अलग होगा: 80vw अब 480 पिक्सल हो गया है.
जब हम अपने सोर्स की चौड़ाई को उससे भाग देते हैं, तो हमें 1.25
, 2.5
, और 4.1666666667
मिलते हैं. व्यूपोर्ट के इस साइज़ में, एक डिवाइस पर small.jpg
को चुना जाएगा और medium.jpg
का मिलान दो डिवाइस पर किया जाएगा.
यह इमेज, ब्राउज़ करने के इन सभी तरीकों में एक जैसी दिखेगी: हमारी सभी सोर्स फ़ाइलें, अपने डाइमेंशन से बिलकुल एक जैसी होती हैं.
साथ ही, हर फ़ाइल उतनी ही तेज़ी से रेंडर होती है जितनी उपयोगकर्ता की डिसप्ले डेंसिटी के हिसाब से होगी. हालांकि, सबसे बड़े व्यूपोर्ट और सबसे ज़्यादा सघनता वाले डिसप्ले को शामिल करने के लिए, हर उपयोगकर्ता को large.jpg
देने के बजाय, उपयोगकर्ताओं को हमेशा सबसे छोटे सही कैंडिडेट को दिखाया जाएगा.
निर्देश देने के बजाय ब्यौरे वाले सिंटैक्स का इस्तेमाल करने पर, आपको मैन्युअल तरीके से ब्रेकपॉइंट सेट करने और आने वाले व्यूपोर्ट और डीपीआर पर ध्यान देने की ज़रूरत नहीं होती. आपको सिर्फ़ ब्राउज़र को जानकारी देनी होती है और इसे आपके जवाबों का पता लगाने की अनुमति देनी होती है.
हमारी sizes
की वैल्यू, व्यूपोर्ट के हिसाब से होती है और पेज के लेआउट से पूरी तरह अलग होती है. इसलिए, यह Android घड़ी के विजेट के साथ बेहतर तरीके से काम करती है.
ऐसा बहुत कम होता है कि ऐसी इमेज हो जो सिर्फ़ व्यूपोर्ट के कुछ प्रतिशत हिस्से का इस्तेमाल करती हो, जिसके लिए पेज पर कोई तय चौड़ाई वाला मार्जिन, पैडिंग या असर न हो. आपको कई बार इकाइयों, प्रतिशत, em
, px
वगैरह के कॉम्बिनेशन का इस्तेमाल करके, इमेज की चौड़ाई बताने की ज़रूरत होगी.
अच्छी बात यह है कि आप यहां calc()
का इस्तेमाल कर सकते हैं. रिस्पॉन्सिव इमेज के लिए नेटिव ब्राउज़र पर भी calc()
का इस्तेमाल किया जा सकता है. इससे हम सीएसएस यूनिट को आपस में मिलाकर, उनका मिलान कर सकते हैं. उदाहरण के लिए, ऐसी इमेज जो उपयोगकर्ता के व्यूपोर्ट की पूरी चौड़ाई लेती है और दोनों के मार्जिन से 1em
को घटाता है:
<img
sizes="calc(100vw-2em)"
srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1600w, x-large.jpg 2400w"
src="fallback.jpg"
alt="...">
ब्रेकपॉइंट के बारे में जानकारी देना
रिस्पॉन्सिव लेआउट के साथ काम करते हुए आपने काफ़ी समय बिताया हो, तो आपने देखा होगा कि इन उदाहरणों में कुछ कमी है:
इस बात की संभावना है कि लेआउट में इमेज ने जो जगह ली है वह हमारे लेआउट के ब्रेकपॉइंट में बदल जाए. इस स्थिति में, आपको ब्राउज़र को थोड़ा और जानकारी देनी होगी: sizes
इमेज के रेंडर किए गए साइज़ के लिए, कॉमा लगाकर अलग किए गए कैंडिडेट के सेट को स्वीकार करता है. ठीक वैसे ही, जैसे srcset
इमेज सोर्स के लिए कॉमा लगाकर अलग किए गए कैंडिडेट स्वीकार करता है. ये शर्तें, जाने-पहचाने मीडिया क्वेरी सिंटैक्स का इस्तेमाल करती हैं.
यह सिंटैक्स फ़र्स्ट मैच पर निर्भर करता है: किसी मीडिया कंडिशन के मैच होते ही ब्राउज़र, sizes
एट्रिब्यूट को पार्स करना बंद कर देता है. साथ ही, तय की गई वैल्यू लागू हो जाती है.
मान लें कि आपके पास एक ऐसी इमेज है जिसका मकसद, 1200 पिक्सल से ज़्यादा के व्यूपोर्ट पर, व्यूपोर्ट के em
को घटाकर, दोनों ओर की पैडिंग (जगह) का 80% हिस्सा कवर करना है. ऐसे व्यूपोर्ट की चौड़ाई, व्यूपोर्ट की पूरी चौड़ाई में होती है.
<img
sizes="(min-width: 1200px) calc(80vw - 2em), 100vw"
srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
src="fallback.jpg"
alt="...">
अगर उपयोगकर्ता का व्यूपोर्ट 1200 पिक्सल से ज़्यादा है, तो calc(80vw - 2em)
हमारे लेआउट में इमेज की चौड़ाई के बारे में बताता है. अगर
(min-width: 1200px)
स्थिति मेल नहीं खाती, तो ब्राउज़र अगली वैल्यू पर चला जाता है. इस वैल्यू से कोई खास मीडिया शर्त नहीं जुड़ी होती है, इसलिए 100vw
को डिफ़ॉल्ट के तौर पर इस्तेमाल किया जाता है. अगर आपको इस sizes
एट्रिब्यूट को max-width
मीडिया क्वेरी का इस्तेमाल करके लिखा गया था, तो:
<img
sizes="(max-width: 1200px) 100vw, calc(80vw - 2em)"
srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
src="fallback.jpg"
alt="...">
आसान भाषा में: "क्या (max-width: 1200px)
मेल खाता है? अगर नहीं, तो आगे बढ़ें. अगली वैल्यू—calc(80vw - 2em)
—के लिए कोई भी शर्त पूरी नहीं की गई है,
इसलिए यह चुनी गई वैल्यू है.
अब आपने ब्राउज़र को अपने img
एलिमेंट से जुड़ी यह पूरी जानकारी दे दी है, जैसे कि संभावित सोर्स, पेज की चौड़ाई, और उपयोगकर्ता को इमेज दिखाने का तरीका. ब्राउज़र उस जानकारी के साथ क्या करना है, यह तय करने के लिए नियमों के एक उलझे हुए सेट का इस्तेमाल करता है. अगर आपको यह समझ नहीं आ रहा, तो इसकी वजह यह है कि ऐसा डिज़ाइन को ध्यान में रखकर किया जाता है. एचटीएमएल स्पेसिफ़िकेशन में एन्कोड किए गए
सोर्स-चुनने का एल्गोरिदम, साफ़ तौर पर यह नहीं बता रहा है कि सोर्स कैसे चुना जाना चाहिए. सोर्स, उनके डिस्क्रिप्टर, और इमेज को रेंडर
करने का तरीका पूरी तरह से पार्स हो गया है. इसके बाद, ब्राउज़र जो चाहे वह कर सकता है—यह नहीं पता कि ब्राउज़र कौनसा सोर्स चुनेगा.
इस सिंटैक्स में "इस सोर्स को हाई-रिज़ॉल्यूशन डिसप्ले पर इस्तेमाल करें" का अनुमान लगाया जा सकता है. हालांकि, इससे रिस्पॉन्सिव लेआउट में इमेज से जुड़ी मुख्य समस्या को हल नहीं किया जा सकेगा. जैसे, उपयोगकर्ता बैंडविथ को बनाए रखना. अगर स्क्रीन की पिक्सल डेंसिटी पर असर हुआ है, तो वह सिर्फ़ इंटरनेट कनेक्शन की स्पीड पर असर डाल सकता है. अगर टॉप-ऑफ़-लाइन लैपटॉप का इस्तेमाल किया जा रहा है, लेकिन सीमित कनेक्शन के ज़रिए, फ़ोन से टेदर किए गए या हवाई जहाज़ के वाई-फ़ाई कनेक्शन का इस्तेमाल करके वेब ब्राउज़ किया जा रहा है, तो आपके डिसप्ले की क्वालिटी पर ध्यान दिए बिना, हाई-रिज़ॉल्यूशन वाली इमेज के सोर्स से ऑप्ट आउट करना बेहतर होगा.
ब्राउज़र को आखिरी निर्देश देने से प्रदर्शन में सुधार करने के लिए उतने ही ज़्यादा सुधार किए जा सकते हैं, जितने कि हम सख्ती से निर्देश वाले
सिंटैक्स से कर सकते हैं. उदाहरण के लिए: ज़्यादातर ब्राउज़र में srcset
या sizes
सिंटैक्स का इस्तेमाल करने वाला img
, उपयोगकर्ता के ब्राउज़र की कैश मेमोरी में पहले से मौजूद डाइमेंशन से छोटे डाइमेंशन वाले सोर्स के लिए अनुरोध करने की ज़रूरत नहीं पड़ेगी. अगर ब्राउज़र एक जैसे दिखने वाले सोर्स के लिए नया अनुरोध करता है, तो इसका क्या मतलब है कि ब्राउज़र उसमें पहले से मौजूद इमेज सोर्स को आसानी से डाउनस्केल कर सकता है? हालांकि, अगर उपयोगकर्ता अपने व्यूपोर्ट को
उस जगह तक स्केल करता है जहां बड़ी इमेज को बढ़ाने से बचने के लिए नई इमेज की ज़रूरत है, तो वह अनुरोध अब भी किया जाएगा,
इसलिए हर चीज़ आपकी उम्मीद के मुताबिक दिखेगी.
साफ़ तौर पर कंट्रोल न कर पाने से आपको थोड़ी डरावनी लग सकती है. हालांकि, एक जैसी कॉन्टेंट वाली सोर्स फ़ाइलों का इस्तेमाल करने की वजह से, सिंगल सोर्स src
के मुकाबले, लोगों को "अधूरा" अनुभव मिलने की संभावना ज़्यादा नहीं होती. भले ही, ब्राउज़र के फ़ैसले कुछ भी हों.
sizes
और srcset
का इस्तेमाल किया जा रहा है
यह आपके, पाठक, और ब्राउज़र, दोनों के लिए बहुत सारी जानकारी होती है. srcset
और sizes
दोनों ही बहुत ज़्यादा सिंटैक्स वाले सिंटैक्स हैं. ये बहुत कम वर्णों में बहुत ज़्यादा जानकारी देते हैं. इसका मतलब है कि डिज़ाइन के हिसाब से, बेहतर या खराब तरीके से: इन सिंटैक्स को कम शब्दों में—और हम इंसानों के लिए आसानी से पार्स करना—इन्हें पार्स करना किसी ब्राउज़र के लिए और मुश्किल हो सकता था. किसी स्ट्रिंग में जितनी जटिलता जोड़ी जाती है, पार्सर गड़बड़ियों या एक ब्राउज़र से दूसरे ब्राउज़र के व्यवहार में अनजाने में अंतर होने की संभावना उतनी ही ज़्यादा होती है. इसमें एक गड़बड़ी है. हालांकि: मशीनों पर आसानी से पढ़ा जा सकने वाला सिंटैक्स, उनके ज़रिए आसानी से लिखा जाने वाला सिंटैक्स होता है.
srcset
, ऑटोमेशन के लिए एक खास केस है. ऐसा बहुत कम होता है कि आप प्रोडक्शन एनवायरमेंट के लिए अपनी इमेज के एक से ज़्यादा वर्शन खुद तैयार करें. इसके लिए, Gulp जैसे टास्क रनर, Webpack जैसे बंडलर, तीसरे पक्ष के Cloudinary जैसे बंडलर या आपकी पसंद के सीएमएस में पहले से मौजूद सुविधा का इस्तेमाल करके प्रोसेस को ऑटोमेट करें. पहली बार में ही हमारे सोर्स जनरेट करने के लिए
काफ़ी जानकारी हो गई हो, तो सिस्टम के पास ज़रूरत के मुताबिक जानकारी होगी, ताकि सोर्स को सही srcset
एट्रिब्यूट में लिखा जा सके.
sizes
को ऑटोमेट करना कुछ ज़्यादा मुश्किल है. जैसा कि आपको पता है, किसी सिस्टम में रेंडर किए गए लेआउट में किसी इमेज के साइज़ का पता लगाने के लिए ही, उस लेआउट को रेंडर करना होता है. अच्छी बात यह है कि कई डेवलपर टूल पॉप-अप हुए हैं, ताकि sizes
एट्रिब्यूट को मैन्युअल तरीके से लिखा जा सके. इनकी बेहतरीन परफ़ॉर्मेंस, कभी भी मैन्युअल तरीके से मैच नहीं की जा सकती.
respImageLint, कोड का एक स्निपेट है, जिसका मकसद आपके sizes
एट्रिब्यूट की सटीक जांच करना है. साथ ही, इसमें सुधार के लिए सुझाव भी दिए जाते हैं. Lazysizes प्रोजेक्ट,
लेआउट तय होने तक इमेज के अनुरोधों को रोककर, बेहतर तरीके से काम करने में रुकावट डालता है. इससे JavaScript आपके लिए sizes
वैल्यू जनरेट कर पाता है. अगर React या Vue जैसे पूरी तरह से क्लाइंट-साइड रेंडरिंग फ़्रेमवर्क का इस्तेमाल किया जा रहा हो, तो srcset
और sizes
एट्रिब्यूट बनाने और/या जनरेट करने से जुड़े कई समाधान मौजूद हैं. इनके बारे में हम सीएमएस और फ़्रेमवर्क में ज़्यादा जानकारी देंगे.