एक लाइन में
इमेज के लिए Base64 एक तस्वीर के बाइनरी डेटा को प्लेन टेक्स्ट की स्ट्रिंग में एनकोड करने का एक तरीका है, जिससे आप इमेज को एक अलग फ़ाइल से लिंक करने के बजाय सीधे कोड में एम्बेड कर सकते हैं।
यह कौन सी समस्या हल करता है
वेब के शुरुआती दिनों में, चीजें आसान थीं: आपके पास आपकी HTML फ़ाइल होती थी, और अगर आपको कोई इमेज चाहिए होती थी, तो आप एक अलग इमेज फ़ाइल, जैसे logo.gif, को इंगित करने के लिए <img> टैग का उपयोग करते थे। ब्राउज़र HTML को पढ़ता, टैग को देखता, और फिर logo.gif को लाने के लिए सर्वर पर एक दूसरा चक्कर लगाता। एक पेज, दो रिक्वेस्ट।
अब, एक आधुनिक वेबपेज की कल्पना करें। इसमें एक लोगो, नेविगेशन के लिए एक दर्जन छोटे आइकन, फुटर में सोशल मीडिया लोगो और एक बैकग्राउंड पैटर्न हो सकता है। अगर इनमें से हर एक एक अलग फ़ाइल है, तो हम अब दो रिक्वेस्ट की बात नहीं कर रहे हैं। हम 20, 30, या उससे भी ज़्यादा की बात कर रहे हैं! हर रिक्वेस्ट का, चाहे फ़ाइल कितनी भी छोटी क्यों न हो, एक ओवरहेड होता है। यह ऐसा है जैसे एक ही गोदाम से एक-एक छोटा पैकेज लेने के लिए 30 छोटी डिलीवरी वैन का एक बेड़ा भेजना। यह अक्षम है और पेज को उपयोगकर्ता के लिए कितनी तेज़ी से दिखाई देता है, इसे धीमा कर देता है।
यही मुख्य समस्या Data URIs और Base64 एन्कोडिंग हल करते हैं: "बहुत सारी रिक्वेस्ट" वाली समस्या। क्या होगा अगर, ब्राउज़र को यह बताने के बजाय कि "जाओ उस आइकन को वहाँ से ले आओ," हम बस यह कह सकते कि "आइकन यहीं है, इस CSS फ़ाइल के अंदर"?
इमेज को टेक्स्ट में परिवर्तित करके और इसे सीधे HTML या CSS में रखकर, आप एसेट्स को दस्तावेज़ के साथ ही बंडल कर देते हैं। यह उन इमेज के लिए अतिरिक्त नेटवर्क रिक्वेस्ट को समाप्त कर देता है, जिससे शुरुआती पेज लोड बहुत तेज़ महसूस होता है, खासकर छोटे, महत्वपूर्ण ग्राफिक्स के लिए। यह एक समझौता है: आपको एक बड़ी शुरुआती HTML/CSS फ़ाइल मिलती है, लेकिन आप कई छोटे आगे-पीछे के नेटवर्क चक्करों का समय और ओवरहेड बचाते हैं।
यह अंदर से कैसे काम करता है
तो, आप एक सुंदर, जटिल इमेज को टेक्स्ट के एक उबाऊ ब्लॉक में कैसे बदलते हैं जो ऐसा दिखता है मानो आपकी बिल्ली कीबोर्ड पर चल दी हो? यह दो-भाग की प्रक्रिया है: इमेज को डेटा के रूप में समझना, और फिर Base64 एन्कोडिंग स्कीम लागू करना।
पिक्सल से बाइट्स तक
पहले, "इमेज" को भूल जाइए। "फ़ाइल" के बारे में सोचिए। आपके कंप्यूटर पर एक PNG, JPEG, या GIF फ़ाइल रंगों का कोई जादुई संग्रह नहीं है। यह बाइट्स का एक अत्यधिक संरचित अनुक्रम है—1s और 0s की एक धारा। इस बाइनरी डेटा में मेटाडेटा (जैसे इमेज के डायमेंशन), कलर पैलेट, और कंप्रेस्ड पिक्सेल डेटा स्वयं शामिल होता है।
समस्या यह है कि आप इस बाइनरी डेटा को सीधे HTML या CSS जैसी टेक्स्ट फ़ाइल में कॉपी-पेस्ट नहीं कर सकते। टेक्स्ट फ़ाइलों के नियम होते हैं। कुछ बाइट वैल्यू का मतलब "नई लाइन," "फ़ाइल का अंत," होता है, या वे बस अमान्य होती हैं और कोड को तोड़ देंगी। हमें इमेज के रॉ बाइनरी डेटा को केवल "सुरक्षित" वर्णों के एक सेट का उपयोग करके प्रस्तुत करने का एक तरीका चाहिए जिसे हर सिस्टम समझता है।
Base64 का जादुई ट्रिक
यहीं पर Base64 एन्कोडिंग कदम रखता है। इसका काम किसी भी बाइनरी डेटा को केवल 64 सामान्य, परिवहन-के-लिए-सुरक्षित ASCII वर्णों का उपयोग करके प्रस्तुत करना है। कैरेक्टर सेट है A-Z, a-z, 0-9, +, और /। बस इतना ही।
यह प्रक्रिया बाइनरी की एक चतुर बाजीगरी है:
- 3 बाइट्स पढ़ें: एन्कोडर बाइनरी इमेज डेटा को एक बार में 3 बाइट्स पढ़ता है। एक बाइट 8 बिट्स का होता है, इसलिए हमारे पास 3 x 8 = 24 बिट्स होते हैं।
- 4 चंक्स में विभाजित करें: यह इस 24-बिट चंक को लेता है और इसे चार 6-बिट चंक्स में फिर से विभाजित करता है (4 x 6 = 24 बिट्स)।
- कैरेक्टर्स से मैप करें: प्रत्येक 6-बिट चंक 0 (000000) से 63 (111111) तक की संख्या का प्रतिनिधित्व कर सकता है। इस संख्या को फिर 64-कैरेक्टर Base64 वर्णमाला में एक कैरेक्टर देखने के लिए एक इंडेक्स के रूप में उपयोग किया जाता है।
आइए इसे एक सरल टेक्स्ट उदाहरण के साथ देखें, क्योंकि सिद्धांत समान है। आइए "cat" शब्द को एनकोड करें:
| चरण | विवरण | डेटा |
|---|---|---|
| 1. असली ASCII | 'c', 'a', 't' के लिए ASCII मान। | 99, 97, 116 |
| 2. 3 बाइट्स (24 बिट्स) के रूप में | प्रत्येक कैरेक्टर के लिए 8-बिट बाइनरी। | 01100011 01100001 01110100 |
| 3. 4 x 6-बिट चंक्स के रूप में | 24 बिट्स को फिर से समूहीकृत किया गया है। | 011000 110110 000101 110100 |
| 4. दशमलव मान | प्रत्येक 6-बिट चंक का दशमलव मान। | 24, 54, 5, 52 |
| 5. Base64 कैरेक्टर | Base64 तालिका में प्रत्येक दशमलव को देखें। | Y, 2, F, 0 |
तो, टेक्स्ट "cat" Base64 स्ट्रिंग "Y2F0" बन जाता है।
क्या होगा अगर डेटा 3 बाइट्स का गुणज नहीं है? एन्कोडर अंत में पैडिंग कैरेक्टर (=) जोड़ता है ताकि यह संकेत मिल सके कि मूल डेटा पूरी तरह से विभाज्य नहीं था। एक = का मतलब है कि अंतिम समूह में केवल दो बाइट्स थे; == का मतलब है कि इसमें केवल एक था।
यह प्रक्रिया डेटा आकार को लगभग 33% बढ़ा देती है, क्योंकि हम 4 कैरेक्टर्स (4 बाइट्स) का उपयोग कर रहे हैं जो मूल रूप से 3 बाइट्स डेटा का प्रतिनिधित्व करने के लिए था।
Data URI रैपर
ठीक है, तो हमारे पास Base64 टेक्स्ट की एक विशाल स्ट्रिंग है। ब्राउज़र स्वचालित रूप से नहीं जानता कि यह एक PNG इमेज है। हमें इसे बताना होगा कि यह Data URI का उपयोग करके क्या देख रहा है।
एक Data URI का एक विशिष्ट प्रारूप होता है:
data:[<MIME-type>][;base64],<data>
आइए एक छोटे लाल डॉट PNG के लिए एक वास्तविक उदाहरण को तोड़ें:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
data:: यह स्कीम है। यह ब्राउज़र को बताता है "डेटा यहीं है, किसी अन्य URL पर नहीं।"image/png: यह MIME टाइप है। यह महत्वपूर्ण है। यह ब्राउज़र को बताता है "मैं जो डेटा दे रहा हूँ वह एक PNG इमेज है। इसे वैसे ही डीकोड करो।" यहimage/jpeg,image/svg+xml, आदि भी हो सकता है।;base64: एक वैकल्पिक फ्लैग जो इंगित करता है कि डेटा Base64-एन्कोडेड है।,: एक सेपरेटर।iVBORw0K...: वास्तविक Base64-एन्कोडेड इमेज डेटा।
जब एक ब्राउज़र इस स्ट्रिंग को <img> src एट्रिब्यूट में या CSS url() फ़ंक्शन में देखता है, तो यह Base64 स्ट्रिंग को वापस मूल बाइनरी बाइट्स में डीकोड करता है और इमेज को प्रस्तुत करता है, यह सब बिना एक भी अतिरिक्त नेटवर्क रिक्वेस्ट किए।
असल दुनिया की कहानियाँ
काँपते हुए UI आइकन्स का मामला
एक फ्रंट-एंड डेवलपर, चलिए उसे प्रिया कहते हैं, एक शानदार नया डैशबोर्ड बना रही थी। इंटरफ़ेस छोटे, सुंदर SVG आइकन्स से भरा था: सेटिंग्स के लिए एक गियर, नोटिफिकेशन के लिए एक घंटी, खोज के लिए एक आवर्धक कांच। उसके तेज़ ऑफिस वाई-फाई पर, यह बहुत अच्छा लग रहा था।
लेकिन जब उसने इसे एक सिम्युलेटेड 3G कनेक्शन पर टेस्ट किया, तो अनुभव चौंकाने वाला था। पेज लेआउट और टेक्स्ट लोड हो जाते, लेकिन एक या दो सेकंड के लिए, उन जगहों पर खाली जगह होती जहाँ आइकन होने चाहिए थे। फिर, वे एक-एक करके दिखाई देते। यह सस्ता और टूटा हुआ लग रहा था।
समस्या यह थी कि 15 आइकनों में से प्रत्येक उसकी CSS फ़ाइल में एक अलग background-image: url(...) था, जो 15 व्यक्तिगत HTTP रिक्वेस्ट को ट्रिगर कर रहा था। प्रिया का समाधान प्रत्येक छोटे SVG को उसके Base64 प्रतिनिधित्व में परिवर्तित करना और इसे सीधे CSS में एम्बेड करना था।
सीख: छोटे, महत्वपूर्ण UI एलिमेंट्स जैसे कि आइकन्स के लिए, उन्हें अपने CSS में Base64 के रूप में एम्बेड करने से रेंडर-ब्लॉकिंग नेटवर्क रिक्वेस्ट समाप्त हो सकती हैं, जिससे गायब इमेज की "फ्लैश" को रोका जा सकता है और एक सहज, अधिक पेशेवर उपयोगकर्ता अनुभव बनाया जा सकता है।
आत्म-निर्भर प्रोजेक्ट प्रस्ताव
एलेक्स, एक कंसल्टेंट, को एक हाई-प्रोफाइल क्लाइंट को एक प्रोजेक्ट प्रस्ताव भेजना था। प्रस्ताव एक HTML दस्तावेज़ था जिसमें PNG इमेज के रूप में उत्पन्न कुछ चार्ट और कंपनी का लोगो था। वह सिर्फ़ फ़ाइलों का एक फ़ोल्डर भेजकर यह भरोसा नहीं कर सकता था कि क्लाइंट HTML को सही ढंग से खोलेगा। ईमेल में अटैचमेंट भेजना भी अटपटा था, और कुछ ईमेल क्लाइंट डिफ़ॉल्ट रूप से बाहरी इमेज को ब्लॉक कर देते हैं।
उसे एक एकल, फुलप्रूफ फ़ाइल की आवश्यकता थी। एक स्क्रिप्ट का उपयोग करके, उसने अंतिम HTML और उत्पन्न चार्ट इमेज को लिया, प्रत्येक इमेज को Base64-एनकोड किया, और <img src="chart1.png"> टैग्स को <img src="data:image/png;base64,..."> से बदल दिया।
परिणाम एक एकल, थोड़ी बड़ी HTML फ़ाइल थी। वह इस एक फ़ाइल को ईमेल में संलग्न कर सकता था, और क्लाइंट इसे ऑनलाइन या ऑफलाइन खोल सकता था, और प्रस्ताव को उसके सभी चार्ट और लोगो के साथ पूरी तरह से रेंडर देख सकता था, बिना किसी सवाल के।
सीख: Base64 पोर्टेबल, आत्म-निर्भर दस्तावेज़ बनाने के लिए एक शानदार उपकरण है। जब आपको इमेज को एक ही फ़ाइल में बंडल करने की आवश्यकता होती है जो हर जगह "बस काम करती है", जैसे ईमेल या जेनरेट की गई रिपोर्ट में, तो यह एकदम सही समाधान है।
आम गलतियाँ और जाल
- बहुत बड़ी इमेज के लिए इसका इस्तेमाल करना। यह सबसे बड़ा पाप है। 33% आकार वृद्धि याद है? 2 MB की हीरो इमेज को अपने HTML के अंदर 2.66 MB के टेक्स्ट ब्लॉक में बदलना परफॉर्मेंस के लिए एक बुरा सपना है। यह आपके पेज को रेंडर होने से रोकेगा, आपके दस्तावेज़ के आकार को बढ़ा देगा, और उपयोगकर्ता के लिए सामान्य रूप से इमेज लोड करने की तुलना में बहुत धीमा होगा। इसका उपयोग केवल छोटी इमेज के लिए करें।
- कैशिंग के नुकसान को नज़रअंदाज़ करना। एक अलग इमेज फ़ाइल (
logo.png) पहली यात्रा के बाद ब्राउज़र द्वारा कैश कर ली जाती है। यदि वह लोगो आपकी साइट के 100 पेजों पर दिखाई देता है, तो इसे केवल एक बार डाउनलोड किया जाता है। यदि आप उस लोगो को उन 100 HTML पेजों में से हर एक में Base64 के रूप में एम्बेड करते हैं, तो उपयोगकर्ता को हर बार उस (बड़े) डेटा को फिर से डाउनलोड करना होगा। - पूरे Data URI सिंटैक्स को भूल जाना। आप बस Base64 स्ट्रिंग को
srcएट्रिब्यूट में नहीं डाल सकते। आपकोdata:, MIME टाइप (image/png,image/jpeg, आदि), और;base64,प्रीफिक्स को शामिल करना अनिवार्य है। इस संदर्भ के बिना, ब्राउज़र को पता नहीं है कि बकवास की स्ट्रिंग के साथ क्या करना है। - अपने CSS को पढ़ने में मुश्किल बनाना। कुछ दर्जन एम्बेडेड इमेज वाली CSS फ़ाइल को मेंटेन करना एक दुःस्वप्न बन सकता है। फ़ाइल हजारों-कैरेक्टर की स्ट्रिंग्स से भर जाती है, जिससे स्क्रॉल करना और वास्तविक स्टाइल नियमों को खोजना मुश्किल हो जाता है। इसका उपयोग विवेकपूर्ण तरीके से करें, और यदि आप एक प्रीप्रोसेसर का उपयोग कर रहे हैं तो Base64 स्ट्रिंग्स को एक अलग फ़ाइल (जैसे Sass वेरिएबल्स) में रखने पर विचार करें।
यह आपके रडार पर क्यों होना चाहिए
आपको एक इमेज को Base64-एनकोड करने के बारे में सोचना चाहिए जब भी आप एक छोटे, महत्वपूर्ण ग्राफिक से निपट रहे हों जिसे आपको तुरंत दिखाना है।
- Above-the-fold आइकन्स: छोटे लोगो, खोज आइकन, या मेनू टॉगल जो शुरुआती उपयोगकर्ता अनुभव के लिए आवश्यक हैं।
- CSS बैकग्राउंड पैटर्न: छोटे, दोहराए जाने वाले पैटर्न जहाँ एक अतिरिक्त HTTP रिक्वेस्ट बहुत ज़्यादा लगती है।
- आत्म-निर्भर दस्तावेज़: जब आप एक एकल HTML फ़ाइल बना रहे हों जिसे बाहरी निर्भरता के बिना अपने दम पर खड़ा होना है (ईमेल, रिपोर्ट, ऑफ़लाइन दस्तावेज़)।
- API रिस्पॉन्स: कभी-कभी, एक API के लिए एक JSON पेलोड के भीतर सीधे एक छोटी थंबनेल इमेज भेजना अधिक कुशल होता है, बजाय इसके कि क्लाइंट को इसके लिए दूसरी रिक्वेस्ट करने के लिए मजबूर किया जाए।
यह एक विशिष्ट काम के लिए एक विशिष्ट उपकरण है: फ़ाइल आकार और नेटवर्क रिक्वेस्ट की संख्या के बीच के समझौते को जीतना। जब बुद्धिमानी से उपयोग किया जाता है, तो यह एक शक्तिशाली ऑप्टिमाइज़ेशन तकनीक है।
और गहराई में जाएं
- RFC 4648: The Base16, Base32, and Base64 Data Encodings - आधिकारिक IETF स्पेसिफिकेशन जो बताता है कि Base64 कैसे काम करता है। यह जितना गीकी और आधिकारिक हो सकता है, उतना है।
- RFC 2397: The "data" URL scheme -
data:प्रोटोकॉल के लिए स्पेसिफिकेशन, जो सिंटैक्स और तर्क को समझाता है। - MDN Web Docs: Data URLs - मोज़िला की ओर से आवश्यक, डेवलपर-फ्रेंडली गाइड, जिसमें स्पष्ट उदाहरण और ब्राउज़र संगतता जानकारी है।
- Wikipedia: Base64 - Base64 एन्कोडिंग स्कीम के इतिहास, उपयोग के मामलों और डिज़ाइन का एक शानदार अवलोकन।
- CSS-Tricks: When to Base64 Encode Images (and When Not To) - वेब डेवलपमेंट के संदर्भ में फायदे और नुकसान पर चर्चा करने वाला एक व्यावहारिक और क्लासिक लेख।